- Timestamp:
- Sep 14, 2015 3:24:42 PM (9 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/VBoxTray
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp
r55401 r57741 7 7 8 8 /* 9 * Copyright (C) 2006-201 4Oracle Corporation9 * Copyright (C) 2006-2015 Oracle Corporation 10 10 * 11 11 * This file is part of VirtualBox Open Source Edition (OSE), as … … 21 21 #include "VBoxHelpers.h" 22 22 23 #include <iprt/asm.h> 24 23 25 #include <VBox/HostServices/VBoxClipboardSvc.h> 24 26 #include <strsafe.h> … … 27 29 #ifdef DEBUG 28 30 # define LOG_ENABLED 29 # define LOG_GROUP LOG_GROUP_ DEFAULT31 # define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD 30 32 #endif 31 33 #include <VBox/log.h> … … 36 38 { 37 39 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. */ 49 static VBOXCLIPBOARDCONTEXT g_Ctx = { NULL }; 50 51 static char s_szClipWndClassName[] = "VBoxSharedClipboardClass"; 59 52 60 53 enum { CBCHAIN_TIMEOUT = 5000 /* ms */ }; 61 54 62 static int vboxClipboardChanged( VBOXCLIPBOARDCONTEXT *pCtx)55 static int vboxClipboardChanged(PVBOXCLIPBOARDCONTEXT pCtx) 63 56 { 64 57 AssertPtr(pCtx); … … 75 68 UINT format = 0; 76 69 77 while ((format = EnumClipboardFormats 70 while ((format = EnumClipboardFormats(format)) != 0) 78 71 { 79 72 LogFlowFunc(("vboxClipboardChanged: format = 0x%08X\n", format)); … … 91 84 92 85 default: 86 { 93 87 if (format >= 0xC000) 94 88 { … … 105 99 } 106 100 break; 101 } 107 102 } 108 103 } 109 104 110 CloseClipboard 105 CloseClipboard(); 111 106 rc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, u32Formats); 112 107 } … … 115 110 116 111 /* Add ourselves into the chain of cliboard listeners */ 117 static void addToCBChain (VBOXCLIPBOARDCONTEXT *pCtx) 118 { 119 pCtx->hwndNextInChain = SetClipboardViewer (pCtx->hwnd); 112 static void vboxClipboardAddToCBChain(PVBOXCLIPBOARDCONTEXT pCtx) 113 { 114 AssertPtrReturnVoid(pCtx); 115 pCtx->hwndNextInChain = SetClipboardViewer(pCtx->hwnd); 116 /** @todo r=andy Return code?? */ 120 117 } 121 118 122 119 /* Remove ourselves from the chain of cliboard listeners */ 123 static void removeFromCBChain (VBOXCLIPBOARDCONTEXT *pCtx) 124 { 125 ChangeClipboardChain (pCtx->hwnd, pCtx->hwndNextInChain); 120 static void vboxClipboardRemoveFromCBChain(PVBOXCLIPBOARDCONTEXT pCtx) 121 { 122 AssertPtrReturnVoid(pCtx); 123 124 ChangeClipboardChain(pCtx->hwnd, pCtx->hwndNextInChain); 126 125 pCtx->hwndNextInChain = NULL; 126 /** @todo r=andy Return code?? */ 127 127 } 128 128 … … 131 131 * There is a race if a ping returns after the next one is initiated, but nothing 132 132 * 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; 133 VOID 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 139 143 pCtx->fCBChainPingInProcess = FALSE; 140 144 } 141 145 142 static LRESULT vboxClipboardProcessMsg(VBOXCLIPBOARDCONTEXT *pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 143 { 146 static LRESULT vboxClipboardProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 147 { 148 AssertPtr(pCtx); 149 144 150 LRESULT rc = 0; 145 151 … … 197 203 if (!hViewer || pCtx->fCBChainPingInProcess) 198 204 { 199 removeFromCBChain(pCtx);200 addToCBChain(pCtx);205 vboxClipboardRemoveFromCBChain(pCtx); 206 vboxClipboardAddToCBChain(pCtx); 201 207 } 202 208 /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be … … 205 211 hViewer = GetClipboardViewer(); 206 212 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); 208 214 } break; 209 215 … … 541 547 } 542 548 543 static LRESULT CALLBACK vboxClipboardWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); 544 545 static int vboxClipboardInit (VBOXCLIPBOARDCONTEXT *pCtx) 546 { 549 static LRESULT CALLBACK vboxClipboardWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 550 551 static 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 547 561 /* 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)) 569 579 { 570 580 /* 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); 576 585 if (pCtx->hwnd == NULL) 577 586 { … … 583 592 SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE); 584 593 585 addToCBChain(pCtx);594 vboxClipboardAddToCBChain(pCtx); 586 595 pCtx->timerRefresh = SetTimer(pCtx->hwnd, 0, 10 * 1000, NULL); 587 596 } 588 597 } 589 598 590 LogFlowFunc (("vboxClipboardInit returned with rc = %Rrc\n", rc));599 LogFlowFuncLeaveRC(rc); 591 600 return rc; 592 601 } 593 602 594 static void vboxClipboardDestroy(VBOXCLIPBOARDCONTEXT *pCtx) 595 { 603 static void vboxClipboardDestroy(PVBOXCLIPBOARDCONTEXT pCtx) 604 { 605 AssertPtrReturnVoid(pCtx); 606 596 607 if (pCtx->hwnd) 597 608 { 598 removeFromCBChain(pCtx);609 vboxClipboardRemoveFromCBChain(pCtx); 599 610 if (pCtx->timerRefresh) 600 611 KillTimer(pCtx->hwnd, 0); 601 612 602 DestroyWindow 613 DestroyWindow(pCtx->hwnd); 603 614 pCtx->hwnd = NULL; 604 615 } 605 616 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 624 static 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 618 629 /* 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 633 DECLCALLBACK(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) 626 641 { 627 642 /* Clipboard was already initialized. 2 or more instances are not supported. */ … … 632 647 { 633 648 /* 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")); 635 650 return VERR_NOT_SUPPORTED; 636 651 } 637 652 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; 649 663 } 650 664 else 651 665 { 652 VbglR3ClipboardDisconnect( gCtx.u32ClientID);666 VbglR3ClipboardDisconnect(pCtx->u32ClientID); 653 667 } 654 668 } 655 669 656 if (RT_SUCCESS(rc)) 657 *ppInstance = &gCtx; 670 LogFlowFuncLeaveRC(rc); 658 671 return rc; 659 672 } 660 673 661 unsigned __stdcall VBoxClipboardThread(void *pInstance) 662 { 663 LogFlowFunc(("VBoxClipboardThread\n")); 664 665 VBOXCLIPBOARDCONTEXT *pCtx = (VBOXCLIPBOARDCONTEXT *)pInstance; 674 DECLCALLBACK(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; 666 686 AssertPtr(pCtx); 687 688 int rc; 667 689 668 690 /* The thread waits for incoming messages from the host. */ … … 671 693 uint32_t u32Msg; 672 694 uint32_t u32Formats; 673 intrc = VbglR3ClipboardGetHostMsg(pCtx->u32ClientID, &u32Msg, &u32Formats);695 rc = VbglR3ClipboardGetHostMsg(pCtx->u32ClientID, &u32Msg, &u32Formats); 674 696 if (RT_FAILURE(rc)) 675 697 { 676 LogFlowFunc(("VBoxClipboardThread: Failed to call the driver for host message! rc = %Rrc\n", rc));677 698 if (rc == VERR_INTERRUPTED) 678 {679 /* Wait for termination event. */680 WaitForSingleObject(pCtx->pEnv->hStopEvent, INFINITE);681 699 break; 682 } 700 701 LogFlowFunc(("Error getting host message, rc=%Rrc\n", rc)); 702 703 if (*pfShutdown) 704 break; 705 683 706 /* 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); 689 708 continue; 690 709 } 691 710 else 692 711 { 693 LogFlowFunc((" VBoxClipboardThread: VbglR3ClipboardGetHostMsg u32Msg = %ld, u32Formats = %ld\n", u32Msg, u32Formats));712 LogFlowFunc(("u32Msg=%RU32, u32Formats=0x%x\n", u32Msg, u32Formats)); 694 713 switch (u32Msg) 695 714 { 715 /** @todo r=andy Use a #define for WM_USER (+1). */ 696 716 case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS: 697 717 { … … 699 719 * Forward the information to the window, so it can later 700 720 * respond to WM_RENDERFORMAT message. */ 701 ::PostMessage 721 ::PostMessage(pCtx->hwnd, WM_USER, 0, u32Formats); 702 722 } break; 703 723 … … 705 725 { 706 726 /* The host needs data in the specified format. */ 707 ::PostMessage 727 ::PostMessage(pCtx->hwnd, WM_USER + 1, 0, u32Formats); 708 728 } break; 709 729 … … 711 731 { 712 732 /* The host is terminating. */ 713 rc = VERR_INTERRUPTED; 733 LogRel(("Clipboard: Terminating ...\n")); 734 ASMAtomicXchgBool(pfShutdown, true); 714 735 } break; 715 736 716 737 default: 717 738 { 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; 720 744 } 721 745 } 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 755 DECLCALLBACK(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 736 764 VbglR3ClipboardDisconnect(pCtx->u32ClientID); 737 memset (pCtx, 0, sizeof (*pCtx)); 765 pCtx->u32ClientID = 0; 766 767 LogFlowFuncLeaveRC(VINF_SUCCESS); 768 return VINF_SUCCESS; 769 } 770 771 DECLCALLBACK(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 738 784 return; 739 785 } 740 786 787 /** 788 * The service description. 789 */ 790 VBOXSERVICEDESC 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 5 5 6 6 /* 7 * Copyright (C) 2006-201 0Oracle Corporation7 * Copyright (C) 2006-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 19 19 #define __VBOXSERVICESHAREDCLIPLBOARD__H 20 20 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 */ 25 22 26 27 #endif /* __VBOXSERVICESHAREDCLIPLBOARD__H */ -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDispIf.cpp
r55401 r57741 53 53 } VBOXDISPIF_OP; 54 54 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 58 55 static DWORD vboxDispIfWddmResizeDisplay(PCVBOXDISPIF const pIf, UINT Id, BOOL fEnable, DISPLAY_DEVICE * paDisplayDevices, DEVMODE *paDeviceMode, UINT devModes); 59 60 56 static DWORD vboxDispIfResizePerform(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes); 61 62 57 static DWORD vboxDispIfWddmEnableDisplaysTryingTopology(PCVBOXDISPIF const pIf, UINT cIds, UINT *pIds, BOOL fEnable); 63 64 58 static DWORD vboxDispIfResizeStartedWDDMOp(VBOXDISPIF_OP *pOp); 65 59 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. 68 63 */ 69 64 typedef struct _VBOXDISPLAYWDDMAPICONTEXT … … 961 956 { 962 957 HRESULT hr = S_OK; 958 959 /** @todo r=andy Use VBOXSERVICEENV::hInstance. */ 963 960 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); 961 964 962 /* 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; 977 970 wc.lpszClassName = VBOXRRWND_NAME; 978 if (!RegisterClass(&wc)) 971 972 if (!RegisterClassEx(&wc)) 979 973 { 980 974 DWORD winErr = GetLastError(); … … 1790 1784 static DWORD vboxDispIfResizeStartedWDDMOp(VBOXDISPIF_OP *pOp) 1791 1785 { 1792 DWORD NumDevices = VBox GetDisplayConfigCount();1786 DWORD NumDevices = VBoxDisplayGetCount(); 1793 1787 if (NumDevices == 0) 1794 1788 { … … 1802 1796 DWORD DevPrimaryNum = 0; 1803 1797 1804 DWORD winEr = VBox GetDisplayConfig(NumDevices, &DevPrimaryNum, &DevNum, paDisplayDevices, paDeviceModes);1798 DWORD winEr = VBoxDisplayGetConfig(NumDevices, &DevPrimaryNum, &DevNum, paDisplayDevices, paDeviceModes); 1805 1799 if (winEr != NO_ERROR) 1806 1800 { … … 1831 1825 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: vboxDispIfWaitDisplayDataInited failed winEr 0x%x\n", winEr)); 1832 1826 1833 DWORD NewNumDevices = VBox GetDisplayConfigCount();1827 DWORD NewNumDevices = VBoxDisplayGetCount(); 1834 1828 if (NewNumDevices == 0) 1835 1829 { … … 1846 1840 DWORD NewDevPrimaryNum = 0; 1847 1841 1848 winEr = VBox GetDisplayConfig(NewNumDevices, &NewDevPrimaryNum, &NewDevNum, paNewDisplayDevices, paNewDeviceModes);1842 winEr = VBoxDisplayGetConfig(NewNumDevices, &NewDevPrimaryNum, &NewDevNum, paNewDisplayDevices, paNewDeviceModes); 1849 1843 if (winEr != NO_ERROR) 1850 1844 { … … 1945 1939 { 1946 1940 DWORD err = NO_ERROR; 1947 AssertBreakpoint(); 1941 1948 1942 OSVERSIONINFO OSinfo; 1949 OSinfo.dwOSVersionInfoSize = sizeof 1943 OSinfo.dwOSVersionInfoSize = sizeof(OSinfo); 1950 1944 GetVersionEx (&OSinfo); 1951 1945 if (OSinfo.dwMajorVersion >= 5) … … 2059 2053 } 2060 2054 2061 static DWORD vboxDispIfSeamles CreateWDDM(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent)2055 static DWORD vboxDispIfSeamlessCreateWDDM(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent) 2062 2056 { 2063 2057 HRESULT hr = vboxDispKmtOpenAdapter(&pIf->modeData.wddm.KmtCallbacks, &pSeamless->modeData.wddm.Adapter); … … 2089 2083 } 2090 2084 2091 static DWORD vboxDispIfSeamles TermWDDM(VBOXDISPIF_SEAMLESS *pSeamless)2085 static DWORD vboxDispIfSeamlessTermWDDM(VBOXDISPIF_SEAMLESS *pSeamless) 2092 2086 { 2093 2087 #ifdef VBOX_DISPIF_WITH_OPCONTEXT … … 2100 2094 } 2101 2095 2102 static DWORD vboxDispIfSeamles SubmitWDDM(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData)2096 static DWORD vboxDispIfSeamlessSubmitWDDM(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData) 2103 2097 { 2104 2098 D3DKMT_ESCAPE EscapeData = {0}; … … 2121 2115 } 2122 2116 2123 DWORD VBoxDispIfSeamles Create(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent)2117 DWORD VBoxDispIfSeamlessCreate(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent) 2124 2118 { 2125 2119 memset(pSeamless, 0, sizeof (*pSeamless)); … … 2134 2128 case VBOXDISPIF_MODE_WDDM: 2135 2129 case VBOXDISPIF_MODE_WDDM_W7: 2136 return vboxDispIfSeamles CreateWDDM(pIf, pSeamless, hEvent);2130 return vboxDispIfSeamlessCreateWDDM(pIf, pSeamless, hEvent); 2137 2131 #endif 2138 2132 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 2140 DWORD VBoxDispIfSeamlessTerm(VBOXDISPIF_SEAMLESS *pSeamless) 2145 2141 { 2146 2142 PCVBOXDISPIF const pIf = pSeamless->pIf; … … 2155 2151 case VBOXDISPIF_MODE_WDDM: 2156 2152 case VBOXDISPIF_MODE_WDDM_W7: 2157 winEr = vboxDispIfSeamles TermWDDM(pSeamless);2153 winEr = vboxDispIfSeamlessTermWDDM(pSeamless); 2158 2154 break; 2159 2155 #endif 2160 2156 default: 2161 WARN(("VBoxTray: VBoxDispIfSeamles Term: invalid mode %d\n", pIf->enmMode));2157 WARN(("VBoxTray: VBoxDispIfSeamlessTerm: invalid mode %d\n", pIf->enmMode)); 2162 2158 winEr = ERROR_INVALID_PARAMETER; 2163 2159 break; … … 2170 2166 } 2171 2167 2172 DWORD VBoxDispIfSeamles Submit(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData)2168 DWORD VBoxDispIfSeamlessSubmit(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData) 2173 2169 { 2174 2170 PCVBOXDISPIF const pIf = pSeamless->pIf; … … 2188 2184 case VBOXDISPIF_MODE_WDDM: 2189 2185 case VBOXDISPIF_MODE_WDDM_W7: 2190 return vboxDispIfSeamles SubmitWDDM(pSeamless, pData, cbData);2186 return vboxDispIfSeamlessSubmitWDDM(pSeamless, pData, cbData); 2191 2187 #endif 2192 2188 default: 2193 WARN(("VBoxTray: VBoxDispIfSeamles Submit: invalid mode %d\n", pIf->enmMode));2189 WARN(("VBoxTray: VBoxDispIfSeamlessSubmit: invalid mode %d\n", pIf->enmMode)); 2194 2190 return ERROR_INVALID_PARAMETER; 2195 2191 } 2196 2192 } 2193 -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDispIf.h
r55401 r57741 51 51 struct 52 52 { 53 LONG (WINAPI * 53 LONG (WINAPI *pfnChangeDisplaySettingsEx)(LPCSTR lpszDeviceName, LPDEVMODE lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam); 54 54 } xpdm; 55 55 #ifdef VBOX_WITH_WDDM … … 57 57 { 58 58 /* 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); 61 60 /* EnumDisplayDevices does not exist in NT. isVBoxDisplayDriverActive et al. are using these functions. */ 62 BOOL (WINAPI * 61 BOOL (WINAPI *pfnEnumDisplayDevices)(IN LPCSTR lpDevice, IN DWORD iDevNum, OUT PDISPLAY_DEVICEA lpDisplayDevice, IN DWORD dwFlags); 63 62 64 63 VBOXDISPKMT_CALLBACKS KmtCallbacks; … … 80 79 DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes); 81 80 DWORD VBoxDispIfCancelPendingResize(PCVBOXDISPIF const pIf); 82 83 81 DWORD VBoxDispIfResizeStarted(PCVBOXDISPIF const pIf); 84 85 82 86 83 typedef struct VBOXDISPIF_SEAMLESS … … 108 105 } 109 106 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); 107 DWORD VBoxDispIfSeamlessCreate(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent); 108 DWORD VBoxDispIfSeamlessTerm(VBOXDISPIF_SEAMLESS *pSeamless); 109 DWORD VBoxDispIfSeamlessSubmit(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData); 110 -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp
r53313 r57741 5 5 6 6 /* 7 * Copyright (C) 2006-201 4Oracle Corporation7 * Copyright (C) 2006-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 42 42 { 43 43 const VBOXSERVICEENV *pEnv; 44 45 44 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. */ 48 46 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. */ 51 48 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 53 static VBOXDISPLAYCONTEXT g_Ctx = { 0 }; 55 54 56 55 #ifdef VBOX_WITH_WDDM … … 65 64 #endif 66 65 67 int VBoxDisplayInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread)66 static DECLCALLBACK(int) VBoxDisplayInit(const PVBOXSERVICEENV pEnv, void **ppInstance) 68 67 { 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); 73 75 GetVersionEx (&OSinfo); 74 76 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; 78 81 79 82 if (NULL == hUser) 80 83 { 81 84 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)); 91 96 92 97 #ifdef VBOX_WITH_WDDM 93 98 if (OSinfo.dwMajorVersion >= 6) 94 99 { 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. */ 96 101 LogFlowFunc(("this is Windows Vista and up\n")); 97 VBOXDISPLAY_DRIVER_TYPE enmType = getVBoxDisplayDriverType (&gCtx);102 VBOXDISPLAY_DRIVER_TYPE enmType = getVBoxDisplayDriverType(pCtx); 98 103 if (enmType == VBOXDISPLAY_DRIVER_TYPE_WDDM) 99 104 { 100 105 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. */ 102 107 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 } 106 114 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 } 108 119 } 109 } 120 else 121 rc = VINF_SUCCESS; 122 } 123 else 124 rc = VINF_SUCCESS; 110 125 #endif 111 126 } 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; 135 154 } 136 155 137 void VBoxDisplayDestroy (const VBOXSERVICEENV *pEnv,void *pInstance)156 static DECLCALLBACK(void) VBoxDisplayDestroy(void *pInstance) 138 157 { 139 158 return; … … 141 160 142 161 #ifdef VBOX_WITH_WDDM 143 static VBOXDISPLAY_DRIVER_TYPE getVBoxDisplayDriverType( VBOXDISPLAYCONTEXT *pCtx)162 static VBOXDISPLAY_DRIVER_TYPE getVBoxDisplayDriverType(PVBOXDISPLAYCONTEXT pCtx) 144 163 #else 145 static bool isVBoxDisplayDriverActive( VBOXDISPLAYCONTEXT *pCtx)164 static bool isVBoxDisplayDriverActive(PVBOXDISPLAYCONTEXT pCtx) 146 165 #endif 147 166 { … … 224 243 } 225 244 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. */ 247 DWORD 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) 228 250 { 229 251 DISPLAY_DEVICE displayDeviceTmp; … … 233 255 DWORD iter ; 234 256 257 PVBOXDISPLAYCONTEXT pCtx = &g_Ctx; /* See todo above. */ 258 235 259 deviceMode = paDeviceModes[Id]; 236 260 displayDevice = paDisplayDevices[Id]; … … 240 264 if (iter != 0 && iter != Id && !(paDisplayDevices[iter].StateFlags & DISPLAY_DEVICE_ACTIVE)) 241 265 { 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)); 243 267 DEVMODE deviceModeTmp; 244 268 ZeroMemory(&deviceModeTmp, sizeof(DEVMODE)); … … 247 271 | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS ; 248 272 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); 251 275 } 252 276 } … … 259 283 if(!(displayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE)) 260 284 { 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)); 262 286 deviceMode.dmPosition.x = paDeviceModes[0].dmPelsWidth; 263 287 deviceMode.dmPosition.y = 0; … … 274 298 deviceMode.dmFields = DM_BITSPERPEL | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY | DM_POSITION; 275 299 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); 277 301 /* A second call to ChangeDisplaySettings updates the monitor.*/ 278 gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);302 pCtx->pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL); 279 303 } 280 304 else /* secondary monitor already enabled. Request to change the resolution or position. */ … … 282 306 if (aWidth !=0 && aHeight != 0) 283 307 { 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)); 285 309 deviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL 286 310 | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS; … … 291 315 if (aPosX != 0 || aPosY != 0) 292 316 { 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)); 294 318 deviceMode.dmFields |= DM_POSITION; 295 319 deviceMode.dmPosition.x = aPosX; 296 320 deviceMode.dmPosition.y = aPosY; 297 321 } 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); 300 324 /* A second call to ChangeDisplaySettings updates the monitor. */ 301 gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);325 pCtx->pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL); 302 326 } 303 327 } 304 328 else /* Request is there to disable the monitor with ID = Id*/ 305 329 { 306 LogRel(("Dis able the Display: %d\n", displayDevice.DeviceName));330 LogRel(("Display [ID=%ld, name='%s']: Disalbing\n", Id, displayDevice.DeviceName)); 307 331 308 332 DEVMODE deviceModeTmp; … … 312 336 | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS ; 313 337 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); 317 341 } 318 342 } … … 320 344 } 321 345 322 DWORD VBox GetDisplayConfigCount()346 DWORD VBoxDisplayGetCount(void) 323 347 { 324 348 DISPLAY_DEVICE DisplayDevice; … … 354 378 } 355 379 356 DWORD VBoxGetDisplayConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes) 380 DWORD VBoxDisplayGetConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, 381 DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes) 357 382 { 358 383 /* Fetch information about current devices and modes. */ … … 441 466 442 467 /* 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? */ 469 static BOOL ResizeDisplayDevice(PVBOXDISPLAYCONTEXT pCtx, 470 UINT Id, DWORD Width, DWORD Height, DWORD BitsPerPixel, 444 471 BOOL fEnabled, LONG dwNewPosX, LONG dwNewPosY, bool fChangeOrigin, 445 VBOXDISPLAYCONTEXT *pCtx,BOOL fExtDispSup)472 BOOL fExtDispSup) 446 473 { 447 474 BOOL fDispAlreadyEnabled = false; /* check whether the monitor with ID is already enabled. */ … … 453 480 Id, Width, Height, dwNewPosX, dwNewPosY, fChangeOrigin, fEnabled, fExtDispSup)); 454 481 455 if (! gCtx.fAnyX)482 if (!pCtx->fAnyX) 456 483 Width &= 0xFFF8; 457 484 458 485 VBoxDispIfCancelPendingResize(&pCtx->pEnv->dispIf); 459 486 460 DWORD NumDevices = VBox GetDisplayConfigCount();487 DWORD NumDevices = VBoxDisplayGetCount(); 461 488 462 489 if (NumDevices == 0 || Id >= NumDevices) … … 473 500 DWORD DevNum = 0; 474 501 DWORD DevPrimaryNum = 0; 475 DWORD dwStatus = VBox GetDisplayConfig(NumDevices, &DevPrimaryNum, &DevNum, paDisplayDevices, paDeviceModes);502 DWORD dwStatus = VBoxDisplayGetConfig(NumDevices, &DevPrimaryNum, &DevNum, paDisplayDevices, paDeviceModes); 476 503 if (dwStatus != NO_ERROR) 477 504 { … … 566 593 * all rect conditions are true. Thus in this case nothing has to be done. 567 594 */ 568 if ( !fModeReset && (!fEnabled == !fDispAlreadyEnabled)569 && paRects[Id].left == dwNewPosX570 && paRects[Id].top == dwNewPosY571 && paRects[Id].right - paRects[Id].left == Width572 && paRects[Id].bottom - paRects[Id].top == Height595 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 573 600 && paDeviceModes[Id].dmBitsPerPel == BitsPerPixel) 574 601 { … … 617 644 618 645 LogFlowFunc(("ResizeDisplayDevice: pfnChangeDisplaySettingsEx %x: %dx%dx%d at %d,%d fields 0x%X\n", 619 gCtx.pfnChangeDisplaySettingsEx,646 pCtx->pfnChangeDisplaySettingsEx, 620 647 paDeviceModes[i].dmPelsWidth, 621 648 paDeviceModes[i].dmPelsHeight, … … 681 708 paDeviceModes[i].dmPosition.y)); 682 709 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); 685 712 LogFlowFunc(("ResizeDisplayDevice: ChangeDisplaySettingsEx position status %d, err %d\n", status, GetLastError ())); 686 713 } … … 706 733 * requests 707 734 */ 708 unsigned __stdcall VBoxDisplayThread(void *pInstance)735 DECLCALLBACK(int) VBoxDisplayWorker(void *pInstance, bool volatile *pfShutdown) 709 736 { 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 713 748 HANDLE gVBoxDriver = pCtx->pEnv->hDriver; 714 bool fTerminate = false;715 749 VBoxGuestFilterMaskInfo maskInfo; 716 750 DWORD cbReturned; … … 720 754 if (!DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL)) 721 755 { 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); 727 762 728 763 VBoxDispIfResizeStarted(&pCtx->pEnv->dispIf); 729 764 730 do 765 int rc = VINF_SUCCESS; 766 767 for (;;) 731 768 { 732 769 BOOL fExtDispSup = TRUE; 733 770 /* Wait for a display change event. */ 734 771 VBoxGuestWaitEventInfo waitEvent; 735 waitEvent.u32TimeoutIn = 1000;772 waitEvent.u32TimeoutIn = 1000; 736 773 waitEvent.u32EventMaskIn = VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST | VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED; 737 774 if (DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent), &waitEvent, sizeof(waitEvent), &cbReturned, NULL)) … … 750 787 751 788 /* are we supposed to stop? */ 752 if ( WaitForSingleObject(pCtx->pEnv->hStopEvent, 0) == WAIT_OBJECT_0)789 if (*pfShutdown) 753 790 break; 754 791 … … 847 884 displayChangeRequest.cyOrigin, 848 885 displayChangeRequest.fChangeOrigin)); 849 if (!ResizeDisplayDevice(displayChangeRequest.display, 886 if (!ResizeDisplayDevice(pCtx, 887 displayChangeRequest.display, 850 888 displayChangeRequest.xres, 851 889 displayChangeRequest.yres, … … 855 893 displayChangeRequest.cyOrigin, 856 894 displayChangeRequest.fChangeOrigin, 857 pCtx,858 895 fExtDispSup 859 896 )) … … 922 959 923 960 LogFlowFunc(("setting new mode %d x %d, %d BPP\n", 924 devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmBitsPerPel));961 devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmBitsPerPel)); 925 962 926 963 /* set the new mode */ … … 955 992 956 993 /* 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); 963 995 } 964 996 } 965 997 else 966 998 { 967 LogFlowFunc(("error from DeviceIoControl VBOXGUEST_IOCTL_VMMREQUEST\n"));968 999 /* 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); 975 1001 } 976 1002 } 1003 1004 /* are we supposed to stop? */ 1005 if (*pfShutdown) 1006 break; 1007 977 1008 if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED) 978 1009 hlpReloadCursor(); … … 980 1011 else 981 1012 { 982 #ifndef DEBUG_andy /* Too noisy for me. */983 LogFlowFunc(("error 0 from DeviceIoControl VBOXGUEST_IOCTL_WAITEVENT\n"));984 #endif985 1013 /* 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) 989 1017 break; 990 } 991 } 992 } while (!fTerminate); 1018 } 1019 } 993 1020 994 1021 /* … … 999 1026 if (!DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL)) 1000 1027 LogFlowFunc(("DeviceIOControl(CtlMask - not) failed\n")); 1001 PostMessage(g hwndToolWindow, 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; 1005 1032 } 1033 1034 /** 1035 * The service description. 1036 */ 1037 VBOXSERVICEDESC 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 5 5 6 6 /* 7 * Copyright (C) 2006-201 0Oracle Corporation7 * Copyright (C) 2006-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 19 19 #define __VBOXSERVICEDISPLAY__H 20 20 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); 21 DWORD VBoxDisplayGetCount(); 22 DWORD VBoxDisplayGetConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes); 25 23 26 DWORD VBoxGetDisplayConfigCount();27 DWORD VBoxGetDisplayConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes);24 DWORD 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); 28 26 29 27 #ifndef VBOX_WITH_WDDM 30 static bool isVBoxDisplayDriverActive 28 static bool isVBoxDisplayDriverActive(void); 31 29 #else 32 30 /* @misha: getVBoxDisplayDriverType is used instead. -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp
r56661 r57741 48 48 #endif 49 49 50 /** The drag and drop window's window class. */ 51 #define VBOX_DND_WND_CLASS "VBoxTrayDnDWnd" 52 50 53 /** @todo Merge this with messages from VBoxTray.h. */ 51 54 #define WM_VBOXTRAY_DND_MESSAGE WM_APP + 401 … … 62 65 static LRESULT CALLBACK vboxDnDWndProcInstance(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 63 66 static LRESULT CALLBACK vboxDnDWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 67 68 static VBOXDNDCONTEXT g_Ctx = { 0 }; 64 69 65 70 VBoxDnDWnd::VBoxDnDWnd(void) … … 97 102 * @param pContext Pointer to context to use. 98 103 */ 99 int VBoxDnDWnd::Initialize(PVBOXDNDCONTEXT pC ontext)100 { 101 AssertPtrReturn(pC ontext, VERR_INVALID_POINTER);104 int VBoxDnDWnd::Initialize(PVBOXDNDCONTEXT pCtx) 105 { 106 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 102 107 103 108 /* Save the context. */ 104 this->pC ontext = pContext;109 this->pCtx = pCtx; 105 110 106 111 int rc = RTSemEventCreate(&mEventSem); … … 113 118 rc = RTThreadCreate(&hThread, VBoxDnDWnd::Thread, this, 114 119 0, RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE, 115 " VBoxTrayDnDWnd");120 "dndwnd"); /** @todo Include ID if there's more than one proxy window. */ 116 121 if (RT_SUCCESS(rc)) 117 122 rc = RTThreadUserWait(hThread, 30 * 1000 /* Timeout in ms */); … … 128 133 * Destroys the proxy window and releases all remaining 129 134 * resources again. 130 *131 135 */ 132 136 void VBoxDnDWnd::Destroy(void) … … 144 148 RTCritSectDelete(&mCritSect); 145 149 if (mEventSem != NIL_RTSEMEVENT) 150 { 146 151 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 } 147 160 148 161 LogFlowFuncLeave(); … … 162 175 AssertPtrReturn(pvUser, VERR_INVALID_POINTER); 163 176 177 LogFlowFuncEnter(); 178 164 179 VBoxDnDWnd *pThis = (VBoxDnDWnd*)pvUser; 165 180 AssertPtr(pThis); 166 181 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; 172 190 Assert(hInstance != 0); 173 191 174 192 /* 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; 183 202 #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))); 186 205 #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 } 198 214 } 199 215 … … 208 224 pThis->hWnd = 209 225 CreateWindowEx(dwExStyle, 210 "VBoxTrayDnDWnd", "VBoxTrayDnDWnd",226 VBOX_DND_WND_CLASS, VBOX_DND_WND_CLASS, 211 227 dwStyle, 212 228 #ifdef VBOX_DND_DEBUG_WND … … 251 267 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 252 268 rc = pThis->RegisterAsDropTarget(); 269 #else 270 rc = VINF_SUCCESS; 253 271 #endif 254 272 } … … 259 277 } 260 278 279 bool fSignalled = false; 280 261 281 if (RT_SUCCESS(rc)) 262 282 { … … 265 285 266 286 bool fShutdown = false; 267 while (RT_SUCCESS(rc))287 for (;;) 268 288 { 269 289 MSG uMsg; … … 274 294 } 275 295 276 if (ASMAtomicReadBool(&pC ontext->fShutdown))296 if (ASMAtomicReadBool(&pCtx->fShutdown)) 277 297 fShutdown = true; 278 298 279 299 if (fShutdown) 280 300 { 281 LogFlowFunc(("C ancelling...\n"));301 LogFlowFunc(("Closing proxy window ...\n")); 282 302 break; 283 303 } … … 356 376 } 357 377 358 case WM_CLOSE: 359 { 360 OnDestroy(); 361 362 DestroyWindow(hWnd); 378 case WM_QUIT: 379 { 380 LogFlowThisFunc(("WM_QUIT\n")); 363 381 PostQuitMessage(0); 364 382 return 0; 365 383 } 366 384 385 case WM_DESTROY: 386 { 387 LogFlowThisFunc(("WM_DESTROY\n")); 388 389 OnDestroy(); 390 return 0; 391 } 392 367 393 case WM_LBUTTONDOWN: 394 { 368 395 LogFlowThisFunc(("WM_LBUTTONDOWN\n")); 369 396 mfMouseButtonDown = true; 370 397 return 0; 398 } 371 399 372 400 case WM_LBUTTONUP: 401 { 373 402 LogFlowThisFunc(("WM_LBUTTONUP\n")); 374 403 mfMouseButtonDown = false; … … 381 410 reset(); 382 411 return 0; 412 } 383 413 384 414 case WM_MOUSELEAVE: 415 { 385 416 LogFlowThisFunc(("WM_MOUSELEAVE\n")); 386 417 return 0; 418 } 387 419 388 420 /* Will only be called once; after the first mouse move, this … … 642 674 { 643 675 pDropTarget = new VBoxDnDDropTarget(this /* pParent */); 644 AssertPtr(pDropTarget);645 676 HRESULT hr = CoLockObjectExternal(pDropTarget, TRUE /* fLock */, 646 677 FALSE /* fLastUnlockReleases */); … … 706 737 int VBoxDnDWnd::OnCreate(void) 707 738 { 739 LogFlowFuncEnter(); 708 740 int rc = VbglR3DnDConnect(&mDnDCtx); 709 741 if (RT_FAILURE(rc)) … … 722 754 void VBoxDnDWnd::OnDestroy(void) 723 755 { 756 DestroyWindow(hWnd); 757 724 758 VbglR3DnDDisconnect(&mDnDCtx); 725 759 LogFlowThisFuncLeave(); … … 812 846 } 813 847 else /* Should never happen. */ 814 AssertRelease FailedBreak(("Format specification for '%s' not implemented\n", pszFormat));848 AssertReleaseMsgFailedBreak(("Format specification for '%s' not implemented\n", pszFormat)); 815 849 break; 816 850 } … … 940 974 /* Post ESC to our window to officially abort the 941 975 * drag and drop operation. */ 942 PostMessage(hWnd, WM_KEYDOWN, VK_ESCAPE, 0 /* lParam */);976 this->PostMessage(WM_KEYDOWN, VK_ESCAPE /* wParam */, 0 /* lParam */); 943 977 944 978 LogFlowFuncLeaveRC(rc); … … 1196 1230 { 1197 1231 case VERR_ACCESS_DENIED: 1198 rc = hlpShowBalloonTip(g hInstance, ghwndToolWindow, ID_TRAYICON,1232 rc = hlpShowBalloonTip(g_hInstance, g_hwndToolWindow, ID_TRAYICON, 1199 1233 szMsg, szTitle, 1200 1234 15 * 1000 /* Time to display in msec */, NIIF_INFO); … … 1270 1304 #endif /* VBOX_WITH_DRAG_AND_DROP_GH */ 1271 1305 1306 void 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 1272 1313 /** 1273 1314 * Injects a DnD event in this proxy window's Windows … … 1282 1323 AssertPtrReturn(pEvent, VERR_INVALID_POINTER); 1283 1324 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 */); 1286 1327 if (!fRc) 1287 1328 { 1329 DWORD dwErr = GetLastError(); 1330 1288 1331 static int s_iBitchedAboutFailedDnDMessages = 0; 1289 1332 if (s_iBitchedAboutFailedDnDMessages++ < 32) 1290 1333 { 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", 1293 1335 pEvent, dwErr, RTErrConvertFromWin32(dwErr))); 1294 1336 } … … 1297 1339 pEvent = NULL; 1298 1340 1299 return VERR_NO_MEMORY;1341 return RTErrConvertFromWin32(dwErr); 1300 1342 } 1301 1343 … … 1561 1603 * @param pfStartThread Pointer to flag whether the DnD service can be started or not. 1562 1604 */ 1563 int VBoxDnDInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread)1605 DECLCALLBACK(int) VBoxDnDInit(const PVBOXSERVICEENV pEnv, void **ppInstance) 1564 1606 { 1565 1607 AssertPtrReturn(pEnv, VERR_INVALID_POINTER); 1566 /** ppInstance not used here. */ 1567 AssertPtrReturn(pfStartThread, VERR_INVALID_POINTER); 1608 AssertPtrReturn(ppInstance, VERR_INVALID_POINTER); 1568 1609 1569 1610 LogFlowFuncEnter(); 1570 1611 1571 *pfStartThread = false; 1572 1573 PVBOXDNDCONTEXT pCtx = &gCtx; 1612 PVBOXDNDCONTEXT pCtx = &g_Ctx; /* Only one instance at the moment. */ 1613 AssertPtr(pCtx); 1574 1614 1575 1615 int rc; 1576 1616 bool fSupportedOS = true; 1577 1617 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")); 1588 1622 rc = VERR_NOT_SUPPORTED; 1589 1623 } 1590 1624 else 1591 1625 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 } 1592 1642 1593 1643 if (RT_SUCCESS(rc)) … … 1619 1669 { 1620 1670 *ppInstance = pCtx; 1621 *pfStartThread = true;1622 1671 1623 1672 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); 1628 1678 return rc; 1629 1679 } 1630 1680 1631 void VBoxDnDStop(const VBOXSERVICEENV *pEnv, void *pInstance) 1632 { 1633 AssertPtrReturnVoid(pEnv); 1634 AssertPtrReturnVoid(pInstance); 1681 DECLCALLBACK(int) VBoxDnDStop(void *pInstance) 1682 { 1683 AssertPtrReturn(pInstance, VERR_INVALID_POINTER); 1635 1684 1636 1685 LogFunc(("Stopping pInstance=%p\n", pInstance)); … … 1641 1690 /* Set shutdown indicator. */ 1642 1691 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 1700 DECLCALLBACK(void) VBoxDnDDestroy(void *pInstance) 1701 { 1702 AssertPtrReturnVoid(pInstance); 1649 1703 1650 1704 LogFunc(("Destroying pInstance=%p\n", pInstance)); … … 1659 1713 VBoxDnDWnd *pWnd = pCtx->lstWnd.first(); 1660 1714 if (pWnd) 1715 { 1661 1716 delete pWnd; 1717 pWnd = NULL; 1718 } 1662 1719 1663 1720 if (pCtx->hEvtQueueSem != NIL_RTSEMEVENT) 1664 1721 RTSemEventDestroy(pCtx->hEvtQueueSem); 1665 1722 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 1726 DECLCALLBACK(int) VBoxDnDWorker(void *pInstance, bool volatile *pfShutdown) 1727 { 1728 AssertPtr(pInstance); 1672 1729 LogFlowFunc(("pInstance=%p\n", pInstance)); 1730 1731 /* 1732 * Tell the control thread that it can continue 1733 * spawning services. 1734 */ 1735 RTThreadUserSignal(RTThreadSelf()); 1673 1736 1674 1737 PVBOXDNDCONTEXT pCtx = (PVBOXDNDCONTEXT)pInstance; 1675 1738 AssertPtr(pCtx); 1676 1739 1677 VBGLR3GUESTDNDCMDCTX ctxDnD; /* The thread's own DnD context. */ 1678 1679 int rc = VbglR3DnDConnect(&ctxDnD); 1740 int rc = VbglR3DnDConnect(&pCtx->cmdCtx); 1680 1741 if (RT_FAILURE(rc)) 1681 1742 return rc; … … 1688 1749 /* Number of invalid messages skipped in a row. */ 1689 1750 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)); 1694 1756 if (!pEvent) 1695 1757 { … … 1699 1761 /* Note: pEvent will be free'd by the consumer later. */ 1700 1762 1701 rc = VbglR3DnDProcessNextMessage(& ctxDnD, &pEvent->Event);1763 rc = VbglR3DnDProcessNextMessage(&pCtx->cmdCtx, &pEvent->Event); 1702 1764 LogFlowFunc(("VbglR3DnDProcessNextMessage returned uType=%RU32, rc=%Rrc\n", 1703 1765 pEvent->Event.uType, rc)); 1704 1766 1705 if (ASMAtomicReadBool(&pCtx->fShutdown))1706 break;1707 1708 1767 if ( RT_SUCCESS(rc) 1709 || rc == VERR_CANCELLED) 1768 /* Cancelled from host. */ 1769 || rc == VERR_CANCELLED 1770 ) 1710 1771 { 1711 1772 cMsgSkippedInvalid = 0; /* Reset skipped messages count. */ 1712 1773 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; 1718 1790 } 1719 1791 else … … 1732 1804 } 1733 1805 1734 int rc2 = VbglR3DnDGHSendError(& ctxDnD, rc);1806 int rc2 = VbglR3DnDGHSendError(&pCtx->cmdCtx, rc); 1735 1807 AssertRC(rc2); 1736 1808 } … … 1741 1813 if (RT_FAILURE(rc)) /* Don't hog the CPU on errors. */ 1742 1814 RTThreadSleep(1000 /* ms */); 1743 1744 } while (true); 1815 } 1816 1817 if (pEvent) 1818 { 1819 RTMemFree(pEvent); 1820 pEvent = NULL; 1821 } 1745 1822 1746 1823 LogFlowFunc(("Shutting down ...\n")); 1747 1824 1748 VbglR3DnDDisconnect(& ctxDnD);1825 VbglR3DnDDisconnect(&pCtx->cmdCtx); 1749 1826 1750 1827 LogFlowFuncLeaveRC(rc); … … 1752 1829 } 1753 1830 1831 /** 1832 * The service description. 1833 */ 1834 VBOXSERVICEDESC 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 23 23 #include <iprt/cpp/mtlist.h> 24 24 #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);30 25 31 26 class VBoxDnDWnd; … … 225 220 /** Shutdown indicator. */ 226 221 bool fShutdown; 222 /** The registered window class. */ 223 ATOM wndClass; 227 224 /** The DnD main event queue. */ 228 225 RTCMTList<VBOXDNDEVENT> lstEvtQueue; … … 233 230 * Note: At the moment only one window is supported. */ 234 231 RTCMTList<VBoxDnDWnd*> lstWnd; 232 /** The DnD command context. */ 233 VBGLR3GUESTDNDCMDCTX cmdCtx; 235 234 236 235 } VBOXDNDCONTEXT, *PVBOXDNDCONTEXT; 237 static VBOXDNDCONTEXT gCtx = {0};238 236 239 237 /** … … 335 333 #endif 336 334 335 void PostMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); 337 336 int ProcessEvent(PVBOXDNDEVENT pEvent); 338 337 … … 352 351 353 352 /** Pointer to DnD context. */ 354 PVBOXDNDCONTEXT pC ontext;353 PVBOXDNDCONTEXT pCtx; 355 354 /** The proxy window's main thread for processing 356 355 * window messages. */ -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHostVersion.cpp
r51469 r57741 6 6 7 7 /* 8 * Copyright (C) 2010-201 4Oracle Corporation8 * Copyright (C) 2010-2015 Oracle Corporation 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 33 33 /** @todo Move this part in VbglR3 and just provide a callback for the platform-specific 34 34 notification stuff, since this is very similar to the VBoxClient code. */ 35 int VBoxCheckHostVersion( )35 int VBoxCheckHostVersion(void) 36 36 { 37 37 int rc; … … 58 58 "install option from the Devices menu.", pszGuestVersion, pszHostVersion); 59 59 60 rc = hlpShowBalloonTip(g hInstance, ghwndToolWindow, ID_TRAYICON,60 rc = hlpShowBalloonTip(g_hInstance, g_hwndToolWindow, ID_TRAYICON, 61 61 szMsg, szTitle, 62 62 5000 /* Time to display in msec */, NIIF_INFO); -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxIPC.cpp
r51469 r57741 7 7 8 8 /* 9 * Copyright (C) 2010-201 4Oracle Corporation9 * Copyright (C) 2010-2015 Oracle Corporation 10 10 * 11 11 * This file is part of VirtualBox Open Source Edition (OSE), as … … 58 58 59 59 } VBOXIPCCONTEXT, *PVBOXIPCCONTEXT; 60 static VBOXIPCCONTEXT gCtx = {0}; 60 61 static VBOXIPCCONTEXT g_Ctx = { 0 }; 61 62 62 63 /** Function pointer for GetLastInputInfo(). */ … … 108 109 { 109 110 /* Showing the balloon tooltip is not critical. */ 110 int rc2 = hlpShowBalloonTip(g hInstance, ghwndToolWindow, ID_TRAYICON,111 int rc2 = hlpShowBalloonTip(g_hInstance, g_hwndToolWindow, ID_TRAYICON, 111 112 ipcMsg.szMsgContent, ipcMsg.szMsgTitle, 112 113 ipcMsg.uShowMS, ipcMsg.uType); … … 163 164 * @return IPRT status code. 164 165 * @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 */ 168 DECLCALLBACK(int) VBoxIPCInit(const PVBOXSERVICEENV pEnv, void **ppInstance) 169 169 { 170 170 AssertPtrReturn(pEnv, VERR_INVALID_POINTER); 171 /** ppInstance not used here. */ 172 AssertPtrReturn(pfStartThread, VERR_INVALID_POINTER); 171 AssertPtrReturn(ppInstance, VERR_INVALID_POINTER); 173 172 174 173 LogFlowFuncEnter(); 175 174 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); 179 179 if (RT_SUCCESS(rc)) 180 180 { … … 195 195 VBOXTRAY_IPC_PIPE_PREFIX, pszUserName)) 196 196 { 197 rc = RTLocalIpcServerCreate(& gCtx.hServer, szPipeName,197 rc = RTLocalIpcServerCreate(&pCtx->hServer, szPipeName, 198 198 RTLOCALIPC_FLAGS_MULTI_SESSION); 199 199 if (RT_SUCCESS(rc)) … … 201 201 RTStrFree(pszUserName); 202 202 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. */ 210 209 s_pfnGetLastInputInfo = (PFNGETLASTINPUTINFO) 211 210 RTLdrGetSystemSymbol("User32.dll", "GetLastInputInfo"); 212 211 213 LogRelFunc(("Local IPC server now running at \"%s\"\n", 214 szPipeName)); 212 LogRelFunc(("Local IPC server now running at \"%s\"\n", szPipeName)); 215 213 return VINF_SUCCESS; 216 214 } … … 224 222 } 225 223 226 RTCritSectDelete(& gCtx.CritSect);224 RTCritSectDelete(&pCtx->CritSect); 227 225 } 228 226 … … 231 229 } 232 230 233 void VBoxIPCStop(const VBOXSERVICEENV *pEnv, void *pInstance) 234 { 235 AssertPtrReturnVoid(pEnv); 231 DECLCALLBACK(void) VBoxIPCStop(void *pInstance) 232 { 236 233 AssertPtrReturnVoid(pInstance); 237 234 … … 267 264 } 268 265 269 void VBoxIPCDestroy(const VBOXSERVICEENV *pEnv, void *pInstance) 270 { 271 AssertPtrReturnVoid(pEnv); 266 DECLCALLBACK(void) VBoxIPCDestroy(void *pInstance) 267 { 272 268 AssertPtrReturnVoid(pInstance); 273 269 … … 476 472 if (pSession) 477 473 { 478 pSession->pCtx = pCtx;479 pSession->hSession = hSession;474 pSession->pCtx = pCtx; 475 pSession->hSession = hSession; 480 476 pSession->fTerminate = false; 481 pSession->hThread = NIL_RTTHREAD;477 pSession->hThread = NIL_RTTHREAD; 482 478 483 479 /* Start IPC session thread. */ … … 485 481 rc = RTThreadCreate(&pSession->hThread, vboxIPCSessionThread, 486 482 pSession /* pvUser */, 0 /* Default stack size */, 487 RTTHREADTYPE_DEFAULT, 0 /* Flags */, " VBXTRYIPCSESS");483 RTTHREADTYPE_DEFAULT, 0 /* Flags */, "IPCSESSION"); 488 484 if (RT_SUCCESS(rc)) 489 485 { … … 529 525 * requests 530 526 */ 531 unsigned __stdcall VBoxIPCThread(void *pInstance) 532 { 527 DECLCALLBACK(int) VBoxIPCWorker(void *pInstance, bool volatile *pfShutdown) 528 { 529 AssertPtr(pInstance); 530 LogFlowFunc(("pInstance=%p\n", pInstance)); 531 533 532 LogFlowFuncEnter(); 533 534 /* 535 * Tell the control thread that it can continue 536 * spawning services. 537 */ 538 RTThreadUserSignal(RTThreadSelf()); 534 539 535 540 PVBOXIPCCONTEXT pCtx = (PVBOXIPCCONTEXT)pInstance; 536 541 AssertPtr(pCtx); 537 542 543 int rc; 544 538 545 bool fShutdown = false; 539 546 for (;;) 540 547 { 541 548 RTLOCALIPCSESSION hClientSession = NIL_RTLOCALIPCSESSION; 542 intrc = RTLocalIpcServerListen(pCtx->hServer, &hClientSession);549 rc = RTLocalIpcServerListen(pCtx->hServer, &hClientSession); 543 550 if (RT_FAILURE(rc)) 544 551 { … … 561 568 } 562 569 563 AssertPtr(pCtx->pEnv); 564 if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 0 /* No waiting */) == WAIT_OBJECT_0) 570 if (*pfShutdown) 565 571 break; 566 572 } 567 573 568 LogFlowFuncLeave(); 569 return 0; 570 } 571 574 LogFlowFuncLeaveRC(rc); 575 return rc; 576 } 577 578 /** 579 * The service description. 580 */ 581 VBOXSERVICEDESC 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 22 22 23 23 int VBoxIPCInit (const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread); 24 unsigned __stdcall VBoxIPC Thread(void *pInstance);24 unsigned __stdcall VBoxIPCWorker (void *pInstance); 25 25 void VBoxIPCStop (const VBOXSERVICEENV *pEnv, void *pInstance); 26 26 void VBoxIPCDestroy (const VBOXSERVICEENV *pEnv, void *pInstance); -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxLA.cpp
r51469 r57741 5 5 6 6 /* 7 * Copyright (C) 2014 Oracle Corporation7 * Copyright (C) 2014-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 54 54 55 55 56 structVBOXLACONTEXT56 typedef struct _VBOXLACONTEXT 57 57 { 58 58 const VBOXSERVICEENV *pEnv; … … 92 92 93 93 BOOL (WINAPI * pfnProcessIdToSessionId)(DWORD dwProcessId, DWORD *pSessionId); 94 } ;95 96 typedef struct ACTIONENTRY94 } VBOXLACONTEXT, *PVBOXLACONTEXT; 95 96 typedef struct _ACTIONENTRY 97 97 { 98 98 RTLISTNODE nodeActionEntry; 99 99 uint32_t u32Index; 100 100 WCHAR wszCommandLine[1]; 101 } ACTIONENTRY ;102 103 104 static VBOXLACONTEXT g Ctx = {0};101 } ACTIONENTRY, *PACTIONENTRY; 102 103 104 static VBOXLACONTEXT g_Ctx = { 0 }; 105 105 106 106 static const char *g_pszPropActiveClient = "/VirtualBox/HostInfo/VRDP/ActiveClient"; … … 407 407 } 408 408 409 static BOOL GetVolatileEnvironmentKey( WCHAR *pwszRegKey, DWORD cbRegKey)409 static BOOL GetVolatileEnvironmentKey(PVBOXLACONTEXT pCtx, WCHAR *pwszRegKey, DWORD cbRegKey) 410 410 { 411 411 BOOL fFound = FALSE; … … 417 417 418 418 /* Attempt to open HKCU\Volatile Environment\<session ID> first. */ 419 if ( gCtx.pfnProcessIdToSessionId != NULL420 && gCtx.pfnProcessIdToSessionId(GetCurrentProcessId(), &nSessionID))419 if ( pCtx->pfnProcessIdToSessionId 420 && pCtx->pfnProcessIdToSessionId(GetCurrentProcessId(), &nSessionID)) 421 421 { 422 422 RTStrPrintf(szRegKey, sizeof(szRegKey), … … 485 485 } 486 486 487 static BOOL GetUtcInfoClientName(WCHAR *pwszClientName, DWORD cbClientName)487 static BOOL laGetUtcInfoClientName(PVBOXLACONTEXT pCtx, WCHAR *pwszClientName, DWORD cbClientName) 488 488 { 489 489 LONG lErr; 490 490 491 491 WCHAR wszRegKey[REG_KEY_LEN]; 492 if (!GetVolatileEnvironmentKey( wszRegKey, sizeof(wszRegKey)))492 if (!GetVolatileEnvironmentKey(pCtx, wszRegKey, sizeof(wszRegKey))) 493 493 { 494 494 return FALSE; … … 561 561 } 562 562 563 static BOOL SetClientName(const WCHAR *pwszClientName)563 static BOOL laSetClientName(PVBOXLACONTEXT pCtx, const WCHAR *pwszClientName) 564 564 { 565 565 LONG lErr; 566 566 567 567 WCHAR wszRegKey[REG_KEY_LEN]; 568 if (!GetVolatileEnvironmentKey( wszRegKey, sizeof(wszRegKey)))568 if (!GetVolatileEnvironmentKey(pCtx, wszRegKey, sizeof(wszRegKey))) 569 569 { 570 570 return FALSE; … … 613 613 &dwResult) == 0) 614 614 { 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 619 static void laUpdateClientName(PVBOXLACONTEXT pCtx) 620 620 { 621 621 WCHAR wszUtcInfoClientName[MAX_CLIENT_NAME_CHARS]; 622 622 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)) 627 626 laBroadcastSettingChange(); 628 } 629 } 630 } 631 632 static void laOnClientLocationInfo(char *pszClientInfo[][2]) 627 } 628 } 629 630 static void laOnClientLocationInfo(PVBOXLACONTEXT pCtx, char *pszClientInfo[][2]) 633 631 { 634 632 /* … … 642 640 unsigned int idx; 643 641 WCHAR wszRegKey[REG_KEY_LEN]; 644 if (!GetVolatileEnvironmentKey( wszRegKey, sizeof(wszRegKey)))642 if (!GetVolatileEnvironmentKey(pCtx, wszRegKey, sizeof(wszRegKey))) 645 643 { 646 644 LogFlowFunc(("Failed to get 'Volatile Environment' registry key\n")); … … 660 658 if (lRet != ERROR_SUCCESS) 661 659 { 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)); 664 661 return; 665 662 } … … 716 713 } 717 714 718 static void laDoAttach( VBOXLACONTEXT *pCtx)715 static void laDoAttach(PVBOXLACONTEXT pCtx) 719 716 { 720 717 LogFlowFunc(("laDoAttach\n")); … … 727 724 } 728 725 729 static void laDoDetach( VBOXLACONTEXT *pCtx)726 static void laDoDetach(PVBOXLACONTEXT pCtx) 730 727 { 731 728 LogFlowFunc(("laDoDetach\n")); … … 836 833 837 834 if (rc != VERR_BUFFER_OVERFLOW) 838 {839 835 break; 840 }841 836 842 837 cbBuf += 1024; … … 877 872 878 873 if (pszValue) 879 {880 874 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)); 886 877 return rc; 887 878 } … … 894 885 ppszValue); 895 886 896 LogFlowFunc(("laGetString: rc = %Rrc, [%s]\n", 897 rc, pszName)); 898 887 LogFlowFunc(("laGetString: rc = %Rrc, [%s]\n", rc, pszName)); 899 888 return rc; 900 889 } 901 890 902 static int laGetActiveClient( VBOXLACONTEXT *pCtx, uint64_t *pu64Timestamp, uint32_t *pu32Value)891 static int laGetActiveClient(PVBOXLACONTEXT pCtx, uint64_t *pu64Timestamp, uint32_t *pu32Value) 903 892 { 904 893 int rc = laGetUint32(pCtx->u32GuestPropHandle, … … 907 896 pu32Value); 908 897 909 LogFlowFunc(("laGetActiveClient: rc %Rrc, %d, %lld\n", rc, *pu32Value, *pu64Timestamp)); 910 898 LogFlowFunc(("laGetActiveClient: rc %Rrc, %RU32, %RU64\n", rc, *pu32Value, *pu64Timestamp)); 911 899 return rc; 912 900 } 913 901 914 static int laUpdateCurrentState( VBOXLACONTEXT *pCtx, uint32_t u32ActiveClientId, uint64_t u64ActiveClientTS)902 static int laUpdateCurrentState(PVBOXLACONTEXT pCtx, uint32_t u32ActiveClientId, uint64_t u64ActiveClientTS) 915 903 { 916 904 /* Prepare the current state for the active client. 917 905 * If u32ActiveClientId is 0, then there is no connected clients. 918 906 */ 919 LogFlowFunc(("laUpdateCurrentState: %u %lld\n", 920 u32ActiveClientId, u64ActiveClientTS)); 907 LogFlowFunc(("laUpdateCurrentState: %RU32 %RU64\n", u32ActiveClientId, u64ActiveClientTS)); 921 908 922 909 int rc = VINF_SUCCESS; … … 1019 1006 } 1020 1007 1021 LogFlowFunc(("laUpdateCurrentState rc = %Rrc\n", 1022 rc)); 1023 1008 LogFlowFunc(("laUpdateCurrentState rc = %Rrc\n", rc)); 1024 1009 return rc; 1025 1010 } 1026 1011 1027 static int laWait(VBOXLACONTEXT *pCtx, uint64_t *pu64Timestamp, uint32_t u32Timeout) 1028 { 1029 LogFlowFunc(("laWait [%s]\n", 1030 pCtx->activeClient.pszPropWaitPattern)); 1012 static int laWait(PVBOXLACONTEXT pCtx, uint64_t *pu64Timestamp, uint32_t u32Timeout) 1013 { 1014 LogFlowFunc(("laWait [%s]\n", pCtx->activeClient.pszPropWaitPattern)); 1031 1015 1032 1016 int rc = laWaitProperties(pCtx->u32GuestPropHandle, … … 1036 1020 u32Timeout); 1037 1021 1038 LogFlowFunc(("laWait rc %Rrc\n", 1039 rc)); 1040 1022 LogFlowFunc(("laWait rc %Rrc\n", rc)); 1041 1023 return rc; 1042 1024 } 1043 1025 1044 static void laProcessClientInfo( VBOXLACONTEXT *pCtx)1026 static void laProcessClientInfo(PVBOXLACONTEXT pCtx) 1045 1027 { 1046 1028 /* Check if the name was changed. */ … … 1066 1048 &pClientInfoMap[idx][LA_UTCINFO_PROP_VALUE]); 1067 1049 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)); 1070 1052 1071 1053 if (RT_FAILURE(rc)) … … 1080 1062 if (u64Timestamp != pCtx->activeClient.u64LastNameTimestamp) 1081 1063 { 1082 laOnClientLocationInfo(pC lientInfoMap);1064 laOnClientLocationInfo(pCtx, pClientInfoMap); 1083 1065 1084 1066 pCtx->activeClient.u64LastNameTimestamp = u64Timestamp; … … 1095 1077 } 1096 1078 1097 static void laProcessAttach( VBOXLACONTEXT *pCtx)1079 static void laProcessAttach(PVBOXLACONTEXT pCtx) 1098 1080 { 1099 1081 /* Check if the attach was changed. */ … … 1110 1092 if (RT_SUCCESS(rc)) 1111 1093 { 1112 LogFlowFunc(("laProcessAttach: read %d, at %lld\n", 1113 u32Attach, u64Timestamp)); 1114 1094 LogFlowFunc(("laProcessAttach: read %RU32, at %RU64\n", u32Attach, u64Timestamp)); 1115 1095 if (u64Timestamp != pCtx->activeClient.u64LastAttachTimestamp) 1116 1096 { … … 1120 1100 1121 1101 /* 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; 1125 1104 1126 1105 pCtx->activeClient.u32LastAttach = u32Attach; … … 1133 1112 * which means that it was changed and restored. 1134 1113 */ 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; 1138 1116 } 1139 1117 … … 1143 1121 } 1144 1122 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 1126 static void laDoActions(PVBOXLACONTEXT pCtx) 1127 { 1128 /* 1129 * Check if the attach was changed. 1152 1130 * 1153 1131 * Caller assumes that this function will filter double actions. 1154 1132 * That is two or more LA_DO_ATTACH will do just one LA_DO_ATTACH. 1155 1133 */ 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)); 1158 1135 1159 1136 switch(pCtx->u32Action) … … 1209 1186 } 1210 1187 1211 int VBoxLAInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread) 1212 { 1213 gCtx.pEnv = pEnv; 1188 DECLCALLBACK(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; 1214 1199 1215 1200 DWORD dwValue = 0; … … 1217 1202 && (dwValue & 0x10) != 0) 1218 1203 { 1219 gCtx.fLogEnabled = true;1204 pCtx->fLogEnabled = true; 1220 1205 } 1221 1206 else 1222 1207 { 1223 gCtx.fLogEnabled = false; 1224 } 1225 1226 LogFlowFunc(("\n")); 1208 pCtx->fLogEnabled = false; 1209 } 1227 1210 1228 1211 /* DetachOnDisconnect is enabled by default. */ … … 1231 1214 && (dwValue & 0x02) == 0) 1232 1215 { 1233 gCtx.fDetachOnDisconnect = false;1216 pCtx->fDetachOnDisconnect = false; 1234 1217 } 1235 1218 else 1236 1219 { 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); 1243 1226 if (RT_FAILURE(rc)) 1244 {1245 1227 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 *p fStartThread = 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); 1256 1238 return VINF_SUCCESS; 1257 1239 } 1258 1240 1259 1260 void VBoxLADestroy(const VBOXSERVICEENV *pEnv, void *pInstance) 1261 { 1262 LogFlowFuncEnter(); 1263 1264 VBOXLACONTEXT *pCtx = (VBOXLACONTEXT *)pInstance; 1241 DECLCALLBACK(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); 1265 1249 1266 1250 if (pCtx->u32GuestPropHandle != 0) … … 1278 1262 * Thread function to wait for and process property changes 1279 1263 */ 1280 unsigned __stdcall VBoxLAThread(void *pInstance) 1281 { 1282 VBOXLACONTEXT *pCtx = (VBOXLACONTEXT *)pInstance; 1283 1284 LogFlowFunc(("Started\n")); 1264 DECLCALLBACK(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; 1285 1276 1286 1277 /* … … 1295 1286 */ 1296 1287 1297 if (!ActionExecutorEnumerateRegistryKey(g_pwszRegKeyReconnectActions, & gCtx.listAttachActions))1288 if (!ActionExecutorEnumerateRegistryKey(g_pwszRegKeyReconnectActions, &pCtx->listAttachActions)) 1298 1289 { 1299 1290 LogFlowFunc(("Can't enumerate registry key %ls\n", g_pwszRegKeyReconnectActions)); 1300 1291 } 1301 if (!ActionExecutorEnumerateRegistryKey(g_pwszRegKeyDisconnectActions, & gCtx.listDetachActions))1292 if (!ActionExecutorEnumerateRegistryKey(g_pwszRegKeyDisconnectActions, &pCtx->listDetachActions)) 1302 1293 { 1303 1294 LogFlowFunc(("Can't enumerate registry key %ls\n", g_pwszRegKeyDisconnectActions)); … … 1308 1299 /* Start at Detached state. */ 1309 1300 pCtx->u32PrevAction = LA_DO_DETACH; 1301 1302 int rc; 1310 1303 1311 1304 for (;;) … … 1323 1316 uint64_t u64Timestamp = 0; 1324 1317 uint32_t u32ActiveClientId = 0; 1325 intrc = laGetActiveClient(pCtx, &u64Timestamp, &u32ActiveClientId);1318 rc = laGetActiveClient(pCtx, &u64Timestamp, &u32ActiveClientId); 1326 1319 1327 1320 if (RT_SUCCESS(rc)) … … 1357 1350 && fClientIdChanged) 1358 1351 { 1359 LogFlowFunc((" client disconnected\n"));1352 LogFlowFunc(("Client disconnected\n")); 1360 1353 1361 1354 /* laDoActions will prevent a repeated detach action. So if there … … 1372 1365 } 1373 1366 1374 /* Check if it is time to exit. 1367 /* 1368 * Check if it is time to exit. 1375 1369 * If the code above failed, wait a bit until repeating to avoid a loop. 1376 1370 * Otherwise just check if the stop event was signalled. 1377 1371 */ 1378 uint32_t u32Wait;1372 RTMSINTERVAL msWait; 1379 1373 if ( rc == VERR_NOT_FOUND 1380 1374 || pCtx->activeClient.u32ClientId == 0) 1381 1375 { 1382 1376 /* No connections, wait longer. */ 1383 u32Wait = 5000; 1377 msWait = 5000; 1378 rc = VINF_SUCCESS; 1384 1379 } 1385 1380 else if (RT_FAILURE(rc)) 1386 1381 { 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; 1388 1387 } 1389 1388 else 1390 { 1391 u32Wait = 0; 1392 } 1393 if (WaitForSingleObject(pCtx->pEnv->hStopEvent, u32Wait) == WAIT_OBJECT_0) 1394 { 1389 msWait = 0; 1390 1391 if (*pfShutdown) 1395 1392 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 */ 1405 VBOXSERVICEDESC 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 5 5 6 6 /* 7 * Copyright (C) 2012 Oracle Corporation7 * Copyright (C) 2012-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 19 19 #define __VBOXSERVICELA__H 20 20 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 */ 24 22 25 #endif /* __VBOXSERVICELA__H */ -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxSeamless.cpp
r51469 r57741 5 5 6 6 /* 7 * Copyright (C) 2006-201 4Oracle Corporation7 * Copyright (C) 2006-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 49 49 50 50 PVBOXDISPIFESCAPE lpEscapeData; 51 } VBOXSEAMLESSCONTEXT ;51 } VBOXSEAMLESSCONTEXT, *PVBOXSEAMLESSCONTEXT; 52 52 53 53 typedef struct … … 57 57 } VBOX_ENUM_PARAM, *PVBOX_ENUM_PARAM; 58 58 59 static VBOXSEAMLESSCONTEXT g Ctx = {0};59 static VBOXSEAMLESSCONTEXT g_Ctx = { 0 }; 60 60 61 61 void VBoxLogString(HANDLE hDriver, char *pszStr); 62 62 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; 63 DECLCALLBACK(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; 70 72 71 73 OSVERSIONINFO OSinfo; … … 73 75 GetVersionEx (&OSinfo); 74 76 75 int rc = VINF_SUCCESS;77 int rc; 76 78 77 79 /* We have to jump out here when using NT4, otherwise it complains about … … 85 87 { 86 88 /* 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); 88 90 if (RT_SUCCESS(rc)) 89 91 { 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"); 92 94 93 95 /* rc should contain success status */ 94 AssertRC(rc); 96 AssertRC(rc); /** @todo r=andy Makes no sense here!? */ 95 97 96 98 VBoxSeamlessSetSupported(TRUE); 97 99 98 // if (RT_SUCCESS(rc)) 99 { 100 *pfStartThread = true; 101 *ppInstance = &gCtx; 102 } 100 *ppInstance = pCtx; 103 101 } 104 102 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); 108 107 return rc; 109 108 } 110 109 111 112 void VBoxSeamlessDestroy(const VBOXSERVICEENV *pEnv, void *pInstance) 113 { 114 Log(("VBoxTray: VBoxSeamlessDestroy\n")); 110 void VBoxSeamlessDestroy(void *pInstance) 111 { 112 LogFlowFuncEnter(); 113 114 PVBOXSEAMLESSCONTEXT pCtx = (PVBOXSEAMLESSCONTEXT)pInstance; 115 AssertPtr(pCtx); 115 116 116 117 VBoxSeamlessSetSupported(FALSE); 117 118 118 119 /* 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; 125 126 } 126 127 return; 127 128 } 128 129 129 static void VBoxSeamlessInstallHook() 130 { 131 if (gCtx.pfnVBoxHookInstallWindowTracker) 130 static 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) 132 136 { 133 137 /* Check current visible region state */ 134 138 VBoxSeamlessCheckWindows(true); 135 139 136 HMODULE hMod = (HMODULE)RTLdrGetNativeHandle( gCtx.hModHook);140 HMODULE hMod = (HMODULE)RTLdrGetNativeHandle(pCtx->hModHook); 137 141 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 146 static 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 161 extern HANDLE g_hSeamlessKmNotifyEvent; 162 163 static VBOXDISPIF_SEAMLESS gVBoxDispIfSeamless; /** @todo r=andy Move this into VBOXSEAMLESSCONTEXT? */ 164 165 166 void 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); 164 174 165 175 VBoxSeamlessInstallHook(); 166 176 } 167 177 168 void VBoxSeamlessDisable() 169 { 178 void 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 170 184 VBoxSeamlessRemoveHook(); 171 185 172 VBoxDispIfSeamles Term(&gVBoxDispIfSeamless);186 VBoxDispIfSeamlessTerm(&gVBoxDispIfSeamless); 173 187 } 174 188 … … 279 293 void VBoxSeamlessCheckWindows(bool fForce) 280 294 { 295 PVBOXSEAMLESSCONTEXT pCtx = &g_Ctx; /** @todo r=andy Use instance data via service lookup (add void *pInstance). */ 296 AssertPtr(pCtx); 297 281 298 if (!VBoxDispIfSeamlesIsValid(&gVBoxDispIfSeamless)) 282 299 return; … … 314 331 } 315 332 #endif 316 LPRGNDATA lpCtxRgnData = VBOXDISPIFESCAPE_DATA( gCtx.lpEscapeData, RGNDATA);333 LPRGNDATA lpCtxRgnData = VBOXDISPIFESCAPE_DATA(pCtx->lpEscapeData, RGNDATA); 317 334 if (fForce 318 || ! gCtx.lpEscapeData335 || !pCtx->lpEscapeData 319 336 || (lpCtxRgnData->rdh.dwSize + lpCtxRgnData->rdh.nRgnSize != cbSize) 320 337 || memcmp(lpCtxRgnData, lpRgnData, cbSize)) 321 338 { 322 339 /* send to display driver */ 323 VBoxDispIfSeamles Submit(&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; 328 345 } 329 346 else 330 347 Log(("VBoxTray: Visible rectangles haven't changed; ignore\n")); 331 348 } 332 if (lpEscapeData != gCtx.lpEscapeData)349 if (lpEscapeData != pCtx->lpEscapeData) 333 350 free(lpEscapeData); 334 351 } … … 345 362 * requests 346 363 */ 347 unsigned __stdcall VBoxSeamlessThread(void *pInstance) 348 { 349 VBOXSEAMLESSCONTEXT *pCtx = (VBOXSEAMLESSCONTEXT *)pInstance; 364 static 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 350 377 HANDLE gVBoxDriver = pCtx->pEnv->hDriver; 351 bool fTerminate = false;352 378 VBoxGuestFilterMaskInfo maskInfo; 353 379 DWORD cbReturned; 354 BOOL fWasScreenSaverActive = FALSE, ret;380 BOOL fWasScreenSaverActive = FALSE, fRet; 355 381 356 382 maskInfo.u32OrMask = VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST; 357 383 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 (;;) 369 394 { 370 395 /* wait for a seamless change event */ … … 374 399 if (DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent), &waitEvent, sizeof(waitEvent), &cbReturned, NULL)) 375 400 { 376 Log(("VBoxTray: VBoxSeamlessThread: DeviceIOControl succeeded\n"));377 378 401 /* are we supposed to stop? */ 379 if ( WaitForSingleObject(pCtx->pEnv->hStopEvent, 0) == WAIT_OBJECT_0)402 if (*pfShutdown) 380 403 break; 381 382 Log(("VBoxTray: VBoxSeamlessThread: checking event\n"));383 404 384 405 /* did we get the right event? */ 385 406 if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST) 386 407 { 387 Log(("VBoxTray: VBoxTray: going to get seamless change information\n"));388 389 408 /* We got at least one event. Read the requested resolution 390 409 * and try to set it until success. New events will not be seen … … 402 421 if (fSeamlessChangeQueried) 403 422 { 404 Log (("VBoxTray: VBoxSeamlessThread: mode changeto %d\n", seamlessChangeRequest.mode));423 LogFlowFunc(("Mode changed to %d\n", seamlessChangeRequest.mode)); 405 424 406 425 switch(seamlessChangeRequest.mode) … … 409 428 if (fWasScreenSaverActive) 410 429 { 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())); 415 434 } 416 PostMessage(g hwndToolWindow, WM_VBOX_SEAMLESS_DISABLE, 0, 0);435 PostMessage(g_hwndToolWindow, WM_VBOX_SEAMLESS_DISABLE, 0, 0); 417 436 break; 418 437 419 438 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())); 423 442 424 443 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(g hwndToolWindow, 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); 431 450 break; 432 451 … … 441 460 } 442 461 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 446 467 /* 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); 453 469 } 454 470 } … … 456 472 else 457 473 { 458 Log(("VBoxTray: VBoxTray: error 0 from DeviceIoControl VBOXGUEST_IOCTL_WAITEVENT\n"));459 474 /* 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 } 468 481 469 482 maskInfo.u32OrMask = 0; 470 483 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 */ 494 VBOXSERVICEDESC 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 5 5 6 6 /* 7 * Copyright (C) 2006-201 0Oracle Corporation7 * Copyright (C) 2006-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 19 19 #define __VBOXSERVICESEAMLESS__H 20 20 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 27 21 void VBoxSeamlessEnable(); 28 22 void VBoxSeamlessDisable(); … … 32 26 33 27 #endif /* __VBOXSERVICESEAMLESS__H */ 28 -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp
r57358 r57741 5 5 6 6 /* 7 * Copyright (C) 2006-201 4Oracle Corporation7 * Copyright (C) 2006-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 44 44 #include <sddl.h> 45 45 46 #include <iprt/asm.h> 46 47 #include <iprt/buildconfig.h> 47 48 #include <iprt/ldr.h> … … 137 138 * Global Variables * 138 139 *********************************************************************************************************************************/ 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; 140 HANDLE g_hVBoxDriver; 141 HANDLE g_hStopSem; 142 HANDLE g_hSeamlessWtNotifyEvent = 0; 143 HANDLE g_hSeamlessKmNotifyEvent = 0; 144 HINSTANCE g_hInstance; 145 HWND g_hwndToolWindow; 146 NOTIFYICONDATA g_NotifyIconData; 147 DWORD g_dwMajorVersion; 149 148 150 149 static PRTLOGGER g_pLoggerRelease = NULL; … … 153 152 static uint64_t g_uHistoryFileSize = 100 * _1M; /* Max 100MB per file. */ 154 153 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 */ 157 static 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 }, 200 165 #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 } 208 167 #endif 209 {210 NULL211 }212 168 }; 213 169 … … 244 200 static int vboxTrayCreateTrayIcon(void) 245 201 { 246 HICON hIcon = LoadIcon(g hInstance, MAKEINTRESOURCE(IDI_VIRTUALBOX));202 HICON hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_VIRTUALBOX)); 247 203 if (hIcon == NULL) 248 204 { 249 205 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)); 251 207 return RTErrConvertFromWin32(dwErr); 252 208 } 253 209 254 210 /* Prepare the system tray icon. */ 255 RT_ZERO(g NotifyIconData);256 g NotifyIconData.cbSize = NOTIFYICONDATA_V1_SIZE; // sizeof(NOTIFYICONDATA);257 g NotifyIconData.hWnd = ghwndToolWindow;258 g NotifyIconData.uID = ID_TRAYICON;259 g NotifyIconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;260 g NotifyIconData.uCallbackMessage = WM_VBOXTRAY_TRAY_ICON;261 g NotifyIconData.hIcon = hIcon;262 263 sprintf(g NotifyIconData.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", 264 220 VBOX_PRODUCT, VBOX_VERSION_MAJOR, VBOX_VERSION_MINOR, VBOX_VERSION_BUILD, VBOX_SVN_REV); 265 221 266 222 int rc = VINF_SUCCESS; 267 if (!Shell_NotifyIcon(NIM_ADD, &g NotifyIconData))223 if (!Shell_NotifyIcon(NIM_ADD, &g_NotifyIconData)) 268 224 { 269 225 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)); 271 227 rc = RTErrConvertFromWin32(dwErr); 272 RT_ZERO(g NotifyIconData);228 RT_ZERO(g_NotifyIconData); 273 229 } 274 230 … … 278 234 } 279 235 280 static void vboxTrayRemoveTrayIcon( )281 { 282 if (g NotifyIconData.cbSize > 0)236 static void vboxTrayRemoveTrayIcon(void) 237 { 238 if (g_NotifyIconData.cbSize > 0) 283 239 { 284 240 /* Remove the system tray icon and refresh system tray. */ 285 Shell_NotifyIcon(NIM_DELETE, &g NotifyIconData);241 Shell_NotifyIcon(NIM_DELETE, &g_NotifyIconData); 286 242 HWND hTrayWnd = FindWindow("Shell_TrayWnd", NULL); /* We assume we only have one tray atm. */ 287 243 if (hTrayWnd) … … 291 247 SendMessage(hTrayNotifyWnd, WM_PAINT, 0, NULL); 292 248 } 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 */ 260 static 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 282 static int vboxTrayServicesStart(PVBOXSERVICEENV pEnv) 298 283 { 299 284 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. */ 334 314 } 335 315 else 336 316 { 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 356 static 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; 416 427 } 417 428 … … 463 474 /* Open VBox guest driver. */ 464 475 DWORD dwErr = ERROR_SUCCESS; 465 g hVBoxDriver = CreateFile(VBOXGUEST_DEVICE_NAME,476 g_hVBoxDriver = CreateFile(VBOXGUEST_DEVICE_NAME, 466 477 GENERIC_READ | GENERIC_WRITE, 467 478 FILE_SHARE_READ | FILE_SHARE_WRITE, … … 470 481 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 471 482 NULL); 472 if (g hVBoxDriver == INVALID_HANDLE_VALUE)483 if (g_hVBoxDriver == INVALID_HANDLE_VALUE) 473 484 { 474 485 dwErr = GetLastError(); … … 480 491 static void vboxTrayCloseBaseDriver(void) 481 492 { 482 if (g hVBoxDriver)483 { 484 CloseHandle(g hVBoxDriver);485 g hVBoxDriver = NULL;493 if (g_hVBoxDriver) 494 { 495 CloseHandle(g_hVBoxDriver); 496 g_hVBoxDriver = NULL; 486 497 } 487 498 } … … 612 623 static void vboxTrayDestroyToolWindow(void) 613 624 { 614 if (g hwndToolWindow)625 if (g_hwndToolWindow) 615 626 { 616 627 Log(("Destroying tool window ...\n")); 617 628 618 629 /* Destroy the tool window. */ 619 DestroyWindow(g hwndToolWindow);620 g hwndToolWindow = NULL;621 622 UnregisterClass("VBoxTrayToolWndClass", g hInstance);630 DestroyWindow(g_hwndToolWindow); 631 g_hwndToolWindow = NULL; 632 633 UnregisterClass("VBoxTrayToolWndClass", g_hInstance); 623 634 } 624 635 } … … 629 640 630 641 /* 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)) 638 651 { 639 652 dwErr = GetLastError(); … … 649 662 * 650 663 */ 651 g hwndToolWindow = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,664 g_hwndToolWindow = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST, 652 665 "VBoxTrayToolWndClass", "VBoxTrayToolWnd", 653 666 WS_POPUPWINDOW, 654 -200, -200, 100, 100, NULL, NULL, g hInstance, NULL);655 if (!g hwndToolWindow)667 -200, -200, 100, 100, NULL, NULL, g_hInstance, NULL); 668 if (!g_hwndToolWindow) 656 669 { 657 670 dwErr = GetLastError(); … … 663 676 hlpReloadCursor(); 664 677 665 Log(("Invisible tool window handle = %p\n", g hwndToolWindow));678 Log(("Invisible tool window handle = %p\n", g_hwndToolWindow)); 666 679 } 667 680 } … … 675 688 { 676 689 OSVERSIONINFO info; 677 g MajorVersion = 5; /* Default to Windows XP. */690 g_dwMajorVersion = 5; /* Default to Windows XP. */ 678 691 info.dwOSVersionInfoSize = sizeof(info); 679 692 if (GetVersionEx(&info)) 680 693 { 681 694 Log(("Windows version %ld.%ld\n", info.dwMajorVersion, info.dwMinorVersion)); 682 g MajorVersion = info.dwMajorVersion;695 g_dwMajorVersion = info.dwMajorVersion; 683 696 } 684 697 … … 702 715 { 703 716 /* For Vista and up we need to change the integrity of the security descriptor, too. */ 704 if (g MajorVersion >= 6)717 if (g_dwMajorVersion >= 6) 705 718 { 706 719 BOOL (WINAPI * pfnConvertStringSecurityDescriptorToSecurityDescriptorA)(LPCSTR StringSecurityDescriptor, DWORD StringSDRevision, PSECURITY_DESCRIPTOR *SecurityDescriptor, PULONG SecurityDescriptorSize); … … 744 757 745 758 if ( dwErr == ERROR_SUCCESS 746 && g MajorVersion >= 5) /* Only for W2K and up ... */747 { 748 g hSeamlessWtNotifyEvent = CreateEvent(&SecAttr, FALSE, FALSE, VBOXHOOK_GLOBAL_WT_EVENT_NAME);749 if (g hSeamlessWtNotifyEvent == 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) 750 763 { 751 764 dwErr = GetLastError(); … … 753 766 } 754 767 755 g hSeamlessKmNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);756 if (g hSeamlessKmNotifyEvent == NULL)768 g_hSeamlessKmNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 769 if (g_hSeamlessKmNotifyEvent == NULL) 757 770 { 758 771 dwErr = GetLastError(); … … 766 779 static void vboxTrayShutdownSeamless(void) 767 780 { 768 if (g hSeamlessWtNotifyEvent)769 { 770 CloseHandle(g hSeamlessWtNotifyEvent);771 g hSeamlessWtNotifyEvent = NULL;772 } 773 774 if (g hSeamlessKmNotifyEvent)775 { 776 CloseHandle(g hSeamlessKmNotifyEvent);777 g hSeamlessKmNotifyEvent = 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; 778 791 } 779 792 } … … 792 805 { 793 806 int rc = VINF_SUCCESS; 794 Log (("Entering vboxTrayServiceMain\n"));795 796 g hStopSem = CreateEvent(NULL, TRUE, FALSE, NULL);797 if (g hStopSem == NULL)807 LogFunc(("Entering vboxTrayServiceMain\n")); 808 809 g_hStopSem = CreateEvent(NULL, TRUE, FALSE, NULL); 810 if (g_hStopSem == NULL) 798 811 { 799 812 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)); 801 814 } 802 815 else … … 806 819 */ 807 820 VBOXSERVICEENV svcEnv; 808 svcEnv.hInstance = g hInstance;809 svcEnv.hDriver = g hVBoxDriver;821 svcEnv.hInstance = g_hInstance; 822 svcEnv.hDriver = g_hVBoxDriver; 810 823 811 824 /* Initializes disp-if to default (XPDM) mode. */ … … 819 832 820 833 /* Finally start all the built-in services! */ 821 rc = vboxTrayS tartServices(&svcEnv, vboxServiceTable);834 rc = vboxTrayServicesStart(&svcEnv); 822 835 if (RT_FAILURE(rc)) 823 836 { 824 837 /* Terminate service if something went wrong. */ 825 vboxTrayS topServices(&svcEnv, vboxServiceTable);838 vboxTrayServicesStop(&svcEnv); 826 839 } 827 840 else … … 829 842 rc = vboxTrayCreateTrayIcon(); 830 843 if ( RT_SUCCESS(rc) 831 && g MajorVersion >= 5) /* Only for W2K and up ... */844 && g_dwMajorVersion >= 5) /* Only for W2K and up ... */ 832 845 { 833 846 /* We're ready to create the tooltip balloon. 834 847 Check in 10 seconds (@todo make seconds configurable) ... */ 835 SetTimer(g hwndToolWindow,848 SetTimer(g_hwndToolWindow, 836 849 TIMERID_VBOXTRAY_CHECK_HOSTVERSION, 837 850 10 * 1000, /* 10 seconds */ … … 864 877 DWORD dwEventCount = 0; 865 878 866 hWaitEvent[dwEventCount++] = g hStopSem;879 hWaitEvent[dwEventCount++] = g_hStopSem; 867 880 868 881 /* Check if seamless mode is not active and add seamless event to the list */ 869 if (0 != g hSeamlessWtNotifyEvent)882 if (0 != g_hSeamlessWtNotifyEvent) 870 883 { 871 hWaitEvent[dwEventCount++] = g hSeamlessWtNotifyEvent;884 hWaitEvent[dwEventCount++] = g_hSeamlessWtNotifyEvent; 872 885 } 873 886 874 if (0 != g hSeamlessKmNotifyEvent)887 if (0 != g_hSeamlessKmNotifyEvent) 875 888 { 876 hWaitEvent[dwEventCount++] = g hSeamlessKmNotifyEvent;889 hWaitEvent[dwEventCount++] = g_hSeamlessKmNotifyEvent; 877 890 } 878 891 … … 882 895 } 883 896 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)); 885 898 while (true) 886 899 { … … 893 906 if (waitResult == 0) 894 907 { 895 Log (("Event 'Exit' triggered\n"));908 LogFunc(("Event 'Exit' triggered\n")); 896 909 /* exit */ 897 910 break; … … 904 917 if (hWaitEvent[waitResult]) 905 918 { 906 if (hWaitEvent[waitResult] == g hSeamlessWtNotifyEvent)919 if (hWaitEvent[waitResult] == g_hSeamlessWtNotifyEvent) 907 920 { 908 Log (("Event 'Seamless' triggered\n"));921 LogFunc(("Event 'Seamless' triggered\n")); 909 922 910 923 /* seamless window notification */ … … 912 925 fHandled = TRUE; 913 926 } 914 else if (hWaitEvent[waitResult] == g hSeamlessKmNotifyEvent)927 else if (hWaitEvent[waitResult] == g_hSeamlessKmNotifyEvent) 915 928 { 916 Log (("Event 'Km Seamless' triggered\n"));929 LogFunc(("Event 'Km Seamless' triggered\n")); 917 930 918 931 /* seamless window notification */ … … 922 935 else if (hWaitEvent[waitResult] == vboxDtGetNotifyEvent()) 923 936 { 924 Log (("Event 'Dt' triggered\n"));937 LogFunc(("Event 'Dt' triggered\n")); 925 938 VBoxTrayCheckDt(); 926 939 fHandled = TRUE; … … 935 948 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 936 949 { 937 #if ndef DEBUG_andy938 Log (("msg %p\n", msg.message));950 #ifdef DEBUG_andy 951 LogFlowFunc(("PeekMessage %u\n", msg.message)); 939 952 #endif 940 953 if (msg.message == WM_QUIT) 941 954 { 942 Log (("WM_QUIT!\n"));943 SetEvent(g hStopSem);955 LogFunc(("Terminating ...\n")); 956 SetEvent(g_hStopSem); 944 957 } 945 958 TranslateMessage(&msg); … … 949 962 } 950 963 } 951 Log (("Returned from main loop, exiting ...\n"));952 } 953 Log (("Waiting for services to stop ...\n"));954 vboxTrayS topServices(&svcEnv, vboxServiceTable);964 LogFunc(("Returned from main loop, exiting ...\n")); 965 } 966 LogFunc(("Waiting for services to stop ...\n")); 967 vboxTrayServicesStop(&svcEnv); 955 968 } /* Services started */ 956 CloseHandle(g hStopSem);969 CloseHandle(g_hStopSem); 957 970 } /* Stop event created */ 958 971 959 972 vboxTrayRemoveTrayIcon(); 960 973 961 Log (("Leaving vboxTrayServiceMainwith rc=%Rrc\n", rc));974 LogFunc(("Leaving with rc=%Rrc\n", rc)); 962 975 return rc; 963 976 } … … 996 1009 { 997 1010 /* Save instance handle. */ 998 g hInstance = hInstance;1011 g_hInstance = hInstance; 999 1012 1000 1013 hlpReportStatus(VBoxGuestFacilityStatus_Init); … … 1004 1017 VBoxCapsInit(); 1005 1018 1006 rc = vboxStInit(g hwndToolWindow);1019 rc = vboxStInit(g_hwndToolWindow); 1007 1020 if (!RT_SUCCESS(rc)) 1008 1021 { 1009 LogFlowFunc(("vboxStInit failed, rc %d\n"));1022 LogFlowFunc(("vboxStInit failed, rc=%Rrc\n", rc)); 1010 1023 /* ignore the St Init failure. this can happen for < XP win that do not support WTS API 1011 1024 * in that case the session is treated as active connected to the physical console … … 1017 1030 if (!RT_SUCCESS(rc)) 1018 1031 { 1019 LogFlowFunc(("vboxDtInit failed, rc %d\n"));1032 LogFlowFunc(("vboxDtInit failed, rc=%Rrc\n", rc)); 1020 1033 /* ignore the Dt Init failure. this can happen for < XP win that do not support WTS API 1021 1034 * in that case the session is treated as active connected to the physical console … … 1026 1039 rc = VBoxAcquireGuestCaps(VMMDEV_GUEST_SUPPORTS_SEAMLESS | VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0, true); 1027 1040 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? */ 1033 1044 if (RT_SUCCESS(rc)) 1034 1045 { 1035 Log(("Init successful\n"));1036 1046 rc = vboxTrayServiceMain(); 1037 1047 if (RT_SUCCESS(rc)) … … 1077 1087 1078 1088 /** 1079 * Window procedure for our tool window1089 * Window procedure for our main tool window. 1080 1090 */ 1081 1091 static LRESULT CALLBACK vboxToolWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 1082 1092 { 1093 LogFlowFunc(("hWnd=%p, uMsg=%u\n", hWnd, uMsg)); 1094 1083 1095 switch (uMsg) 1084 1096 { 1085 1097 case WM_CREATE: 1086 1098 { 1087 Log (("Tool window created\n"));1099 LogFunc(("Tool window created\n")); 1088 1100 1089 1101 int rc = vboxTrayRegisterGlobalMessages(&s_vboxGlobalMessageTable[0]); 1090 1102 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)); 1092 1104 return 0; 1093 1105 } … … 1097 1109 1098 1110 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); 1101 1114 return 0; 1115 } 1102 1116 1103 1117 case WM_TIMER: 1118 { 1104 1119 if (VBoxCapsCheckTimer(wParam)) 1105 1120 return 0; … … 1115 1130 { 1116 1131 /* After successful run we don't need to check again. */ 1117 KillTimer(g hwndToolWindow, TIMERID_VBOXTRAY_CHECK_HOSTVERSION);1132 KillTimer(g_hwndToolWindow, TIMERID_VBOXTRAY_CHECK_HOSTVERSION); 1118 1133 } 1119 1134 return 0; … … 1122 1137 break; 1123 1138 } 1139 1124 1140 break; /* Make sure other timers get processed the usual way! */ 1141 } 1125 1142 1126 1143 case WM_VBOXTRAY_TRAY_ICON: 1144 { 1127 1145 switch (lParam) 1128 1146 { … … 1134 1152 } 1135 1153 return 0; 1154 } 1136 1155 1137 1156 case WM_VBOX_SEAMLESS_ENABLE: 1157 { 1138 1158 VBoxCapsEntryFuncStateSet(VBOXCAPS_ENTRY_IDX_SEAMLESS, VBOXCAPS_ENTRY_FUNCSTATE_STARTED); 1139 1159 return 0; 1160 } 1140 1161 1141 1162 case WM_VBOX_SEAMLESS_DISABLE: 1163 { 1142 1164 VBoxCapsEntryFuncStateSet(VBOXCAPS_ENTRY_IDX_SEAMLESS, VBOXCAPS_ENTRY_FUNCSTATE_SUPPORTED); 1143 1165 return 0; 1166 } 1144 1167 1145 1168 case WM_DISPLAYCHANGE: 1146 1169 case WM_VBOX_SEAMLESS_UPDATE: 1170 { 1147 1171 if (VBoxCapsEntryIsEnabled(VBOXCAPS_ENTRY_IDX_SEAMLESS)) 1148 1172 VBoxSeamlessCheckWindows(true); 1149 1173 return 0; 1174 } 1150 1175 1151 1176 case WM_VBOX_GRAPHICS_SUPPORTED: 1177 { 1152 1178 VBoxGrapicsSetSupported(TRUE); 1153 1179 return 0; 1180 } 1154 1181 1155 1182 case WM_VBOX_GRAPHICS_UNSUPPORTED: 1183 { 1156 1184 VBoxGrapicsSetSupported(FALSE); 1157 1185 return 0; 1186 } 1158 1187 1159 1188 case WM_WTSSESSION_CHANGE: … … 1167 1196 return 0; 1168 1197 } 1198 1169 1199 default: 1170 1200 { 1171 1201 /* Handle all globally registered window messages. */ 1172 1202 if (vboxTrayHandleGlobalMessages(&s_vboxGlobalMessageTable[0], uMsg, … … 1176 1206 } 1177 1207 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. */ 1182 1212 return DefWindowProc(hWnd, uMsg, wParam, lParam); 1183 1213 } … … 1443 1473 int rc = VINF_SUCCESS; 1444 1474 OSVERSIONINFO info; 1445 g MajorVersion = 5; /* Default to Windows XP. */1475 g_dwMajorVersion = 5; /* Default to Windows XP. */ 1446 1476 info.dwOSVersionInfoSize = sizeof(info); 1447 1477 if (GetVersionEx(&info)) 1448 1478 { 1449 1479 LogRel(("Windows version %ld.%ld\n", info.dwMajorVersion, info.dwMinorVersion)); 1450 g MajorVersion = info.dwMajorVersion;1480 g_dwMajorVersion = info.dwMajorVersion; 1451 1481 } 1452 1482 … … 1499 1529 BOOL fRc = FALSE; 1500 1530 /* For Vista and up we need to change the integrity of the security descriptor, too. */ 1501 if (g MajorVersion >= 6)1531 if (g_dwMajorVersion >= 6) 1502 1532 { 1503 1533 HMODULE hModHook = (HMODULE)RTLdrGetNativeHandle(gVBoxDt.hLdrModHook); … … 1513 1543 if (!fRc) 1514 1544 { 1515 gVBoxDt.idTimer = SetTimer(g hwndToolWindow, TIMERID_VBOXTRAY_DT_TIMER, 500, (TIMERPROC)NULL);1545 gVBoxDt.idTimer = SetTimer(g_hwndToolWindow, TIMERID_VBOXTRAY_DT_TIMER, 500, (TIMERPROC)NULL); 1516 1546 if (!gVBoxDt.idTimer) 1517 1547 { … … 1586 1616 } 1587 1617 1588 1589 1618 /* we need to perform Acquire/Release using the file handled we use for rewuesting events from VBoxGuest 1590 1619 * otherwise Acquisition mechanism will treat us as different client and will not propagate necessary requests … … 1599 1628 Info.u32OrMask = fOr; 1600 1629 Info.u32NotMask = fNot; 1601 if (!DeviceIoControl(g hVBoxDriver, 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)) 1602 1631 { 1603 1632 DWORD LastErr = GetLastError(); … … 1650 1679 static VBOXCAPS gVBoxCaps; 1651 1680 1652 static DECLCALLBACK(void) vboxCapsOnEnableSeamles (struct VBOXCAPS *pConsole, struct VBOXCAPS_ENTRY *pCap, BOOL fEnabled)1681 static DECLCALLBACK(void) vboxCapsOnEnableSeamless(struct VBOXCAPS *pConsole, struct VBOXCAPS_ENTRY *pCap, BOOL fEnabled) 1653 1682 { 1654 1683 if (fEnabled) 1655 1684 { 1656 Log(("vboxCapsOnEnableSeamles : ENABLED\n"));1685 Log(("vboxCapsOnEnableSeamless: ENABLED\n")); 1657 1686 Assert(pCap->enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED); 1658 1687 Assert(pCap->enmFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED); … … 1661 1690 else 1662 1691 { 1663 Log(("vboxCapsOnEnableSeamles : DISABLED\n"));1692 Log(("vboxCapsOnEnableSeamless: DISABLED\n")); 1664 1693 Assert(pCap->enmAcState != VBOXCAPS_ENTRY_ACSTATE_ACQUIRED || pCap->enmFuncState != VBOXCAPS_ENTRY_FUNCSTATE_STARTED); 1665 1694 VBoxSeamlessDisable(); … … 1738 1767 pConsole->aCaps[VBOXCAPS_ENTRY_IDX_SEAMLESS].fCap = VMMDEV_GUEST_SUPPORTS_SEAMLESS; 1739 1768 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; 1741 1770 pConsole->aCaps[VBOXCAPS_ENTRY_IDX_GRAPHICS].fCap = VMMDEV_GUEST_SUPPORTS_GRAPHICS; 1742 1771 pConsole->aCaps[VBOXCAPS_ENTRY_IDX_GRAPHICS].iCap = VBOXCAPS_ENTRY_IDX_GRAPHICS; … … 1758 1787 { 1759 1788 Log(("killing console timer\n")); 1760 KillTimer(g hwndToolWindow, pConsole->idTimer);1789 KillTimer(g_hwndToolWindow, pConsole->idTimer); 1761 1790 pConsole->idTimer = 0; 1762 1791 } … … 1820 1849 if (!fNeedNewTimer) 1821 1850 { 1822 KillTimer(g hwndToolWindow, pConsole->idTimer);1851 KillTimer(g_hwndToolWindow, pConsole->idTimer); 1823 1852 /* cleanup timer data */ 1824 1853 pConsole->idTimer = 0; … … 1881 1910 if (!pConsole->idTimer) 1882 1911 { 1883 pConsole->idTimer = SetTimer(g hwndToolWindow, TIMERID_VBOXTRAY_CAPS_TIMER, 100, (TIMERPROC)NULL);1912 pConsole->idTimer = SetTimer(g_hwndToolWindow, TIMERID_VBOXTRAY_CAPS_TIMER, 100, (TIMERPROC)NULL); 1884 1913 if (!pConsole->idTimer) 1885 1914 { -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.h
r51469 r57741 5 5 6 6 /* 7 * Copyright (C) 2006-201 4Oracle Corporation7 * Copyright (C) 2006-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 46 46 #include <iprt/initterm.h> 47 47 #include <iprt/string.h> 48 #include <iprt/thread.h> 48 49 49 50 #include <VBox/version.h> … … 63 64 #define WM_VBOXTRAY_TRAY_ICON WM_APP + 40 64 65 65 66 66 /* The tray icon's ID. */ 67 67 #define ID_TRAYICON 2000 68 69 68 70 69 /* … … 76 75 #define TIMERID_VBOXTRAY_ST_DELAYED_INIT_TIMER 1003 77 76 78 /* The environment information for services. */ 77 /** 78 * The environment information for services. 79 */ 79 80 typedef struct _VBOXSERVICEENV 80 81 { 82 /** hInstance of VBoxTray. */ 81 83 HINSTANCE hInstance; 84 /** Handle of guest driver. */ 82 85 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. */ 85 89 VBOXDISPIF dispIf; 86 } VBOXSERVICEENV ;90 } VBOXSERVICEENV, *PVBOXSERVICEENV; 87 91 88 /* The service initialization info and runtime variables. */ 92 /** 93 * A service descriptor. 94 */ 95 typedef 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 135 extern VBOXSERVICEDESC g_SvcDescDisplay; 136 extern VBOXSERVICEDESC g_SvcDescClipboard; 137 extern VBOXSERVICEDESC g_SvcDescSeamless; 138 extern VBOXSERVICEDESC g_SvcDescVRDP; 139 extern VBOXSERVICEDESC g_SvcDescIPC; 140 extern VBOXSERVICEDESC g_SvcDescLA; 141 #ifdef VBOX_WITH_DRAG_AND_DROP 142 extern VBOXSERVICEDESC g_SvcDescDnD; 143 #endif 144 145 /** 146 * The service initialization info and runtime variables. 147 */ 89 148 typedef struct _VBOXSERVICEINFO 90 149 { 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; 102 168 103 169 /* Globally unique (system wide) message registration. */ … … 116 182 } VBOXGLOBALMESSAGE, *PVBOXGLOBALMESSAGE; 117 183 118 extern HWND g hwndToolWindow;119 extern HINSTANCE g hInstance;184 extern HWND g_hwndToolWindow; 185 extern HINSTANCE g_hInstance; 120 186 121 187 #endif /* !___VBOXTRAY_H */ -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxVRDP.cpp
r51469 r57741 5 5 6 6 /* 7 * Copyright (C) 2006-201 4Oracle Corporation7 * Copyright (C) 2006-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 59 59 }; 60 60 61 typedef struct _VB oxExperienceParameter61 typedef struct _VBOXVRDPEXPPARAM 62 62 { 63 63 const char *name; … … 69 69 UINT cbSavedValue; 70 70 char achSavedValue[2 * MAX_PATH]; /* Large enough to save the bitmap path. */ 71 } VBoxExperienceParameter; 71 } VBOXVRDPEXPPARAM, *PVBOXVRDPEXPPARAM; 72 73 typedef 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 86 static VBOXVRDPCONTEXT g_Ctx = { 0 }; 72 87 73 88 #define SPI_(l, a) #a, SPI_SET##a, SPI_GET##a, VRDP_EXPERIENCE_LEVEL_##l 74 89 75 static VB oxExperienceParameter parameters[] =90 static VBOXVRDPEXPPARAM s_aSPIParams[] = 76 91 { 77 92 { SPI_(MEDIUM, DESKWALLPAPER), VBOX_SPI_STRING, "" }, … … 92 107 #undef SPI_ 93 108 94 static void vboxExperienceSet (uint32_t level)95 { 96 int i;97 for (i = 0; i < RT_ELEMENTS(parameters); i++)98 {99 if (p arameters[i].level > level)109 static 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) 100 115 { 101 116 /* 102 117 * The parameter has to be disabled. 103 118 */ 104 LogFlowFunc(("Saving %s\n", p arameters[i].name));119 LogFlowFunc(("Saving %s\n", pParam->name)); 105 120 106 121 /* Save the current value. */ 107 switch (p arameters[i].type)122 switch (pParam->type) 108 123 { 109 124 case VBOX_SPI_STRING: … … 112 127 * The 3rd parameter points to the buffer. 113 128 */ 114 SystemParametersInfo (p arameters[i].uActionGet,129 SystemParametersInfo (pParam->uActionGet, 115 130 MAX_PATH, 116 p arameters[i].achSavedValue,131 pParam->achSavedValue, 117 132 0); 118 133 } break; … … 122 137 { 123 138 /* The 3rd parameter points to BOOL. */ 124 SystemParametersInfo (p arameters[i].uActionGet,125 0, 126 p arameters[i].achSavedValue,139 SystemParametersInfo (pParam->uActionGet, 140 0, 141 pParam->achSavedValue, 127 142 0); 128 143 } break; … … 134 149 * The uiParam parameter must alos be set. 135 150 */ 136 if (p arameters[i].cbSavedValue > sizeof (parameters[i].achSavedValue))151 if (pParam->cbSavedValue > sizeof (pParam->achSavedValue)) 137 152 { 138 LogFlowFunc(("Not enough space %d > %d\n", p arameters[i].cbSavedValue, sizeof (parameters[i].achSavedValue)));153 LogFlowFunc(("Not enough space %d > %d\n", pParam->cbSavedValue, sizeof (pParam->achSavedValue))); 139 154 break; 140 155 } 141 156 142 *(UINT *)&p arameters[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, 147 162 0); 148 163 } break; … … 152 167 } 153 168 154 LogFlowFunc(("Disabling %s\n", p arameters[i].name));169 LogFlowFunc(("Disabling %s\n", pParam->name)); 155 170 156 171 /* Disable the feature. */ 157 switch (p arameters[i].type)172 switch (pParam->type) 158 173 { 159 174 case VBOX_SPI_STRING: 160 175 { 161 176 /* The 3rd parameter points to the string. */ 162 SystemParametersInfo (p arameters[i].uActionSet,163 0, 164 p arameters[i].pvDisable,177 SystemParametersInfo (pParam->uActionSet, 178 0, 179 pParam->pvDisable, 165 180 SPIF_SENDCHANGE); 166 181 } break; … … 169 184 { 170 185 /* The 2nd parameter is BOOL. */ 171 SystemParametersInfo (p arameters[i].uActionSet,186 SystemParametersInfo (pParam->uActionSet, 172 187 FALSE, 173 188 NULL, … … 178 193 { 179 194 /* The 3rd parameter is NULL to disable. */ 180 SystemParametersInfo (p arameters[i].uActionSet,195 SystemParametersInfo (pParam->uActionSet, 181 196 0, 182 197 NULL, … … 187 202 { 188 203 /* The 3rd parameter points to the structure. */ 189 SystemParametersInfo (p arameters[i].uActionSet,190 0, 191 p arameters[i].pvDisable,204 SystemParametersInfo (pParam->uActionSet, 205 0, 206 pParam->pvDisable, 192 207 SPIF_SENDCHANGE); 193 208 } break; … … 200 215 } 201 216 202 static void vboxExperienceRestore (uint32_t level)217 static void vboxExperienceRestore(uint32_t uLevel) 203 218 { 204 219 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) 208 224 { 209 LogFlowFunc(("Restoring %s\n", p arameters[i].name));225 LogFlowFunc(("Restoring %s\n", pParam->name)); 210 226 211 227 /* Restore the feature. */ 212 switch (p arameters[i].type)228 switch (pParam->type) 213 229 { 214 230 case VBOX_SPI_STRING: 215 231 { 216 232 /* The 3rd parameter points to the string. */ 217 SystemParametersInfo (p arameters[i].uActionSet,218 0, 219 p arameters[i].achSavedValue,233 SystemParametersInfo (pParam->uActionSet, 234 0, 235 pParam->achSavedValue, 220 236 SPIF_SENDCHANGE); 221 237 } break; … … 224 240 { 225 241 /* The 2nd parameter is BOOL. */ 226 SystemParametersInfo (p arameters[i].uActionSet,227 *(BOOL *)&p arameters[i].achSavedValue[0],242 SystemParametersInfo (pParam->uActionSet, 243 *(BOOL *)&pParam->achSavedValue[0], 228 244 NULL, 229 245 SPIF_SENDCHANGE); … … 233 249 { 234 250 /* The 3rd parameter is NULL to disable. */ 235 BOOL fSaved = *(BOOL *)&p arameters[i].achSavedValue[0];236 237 SystemParametersInfo (p arameters[i].uActionSet,251 BOOL fSaved = *(BOOL *)&pParam->achSavedValue[0]; 252 253 SystemParametersInfo (pParam->uActionSet, 238 254 0, 239 255 fSaved? &fSaved: NULL, … … 244 260 { 245 261 /* The 3rd parameter points to the structure. */ 246 SystemParametersInfo (p arameters[i].uActionSet,247 0, 248 p arameters[i].achSavedValue,262 SystemParametersInfo (pParam->uActionSet, 263 0, 264 pParam->achSavedValue, 249 265 SPIF_SENDCHANGE); 250 266 } break; … … 257 273 } 258 274 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); 275 static 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); 286 290 if (RT_SUCCESS(rc)) 287 291 { 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; 290 296 } 291 297 else 292 298 { 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; 301 306 } 302 307 303 304 void VBoxVRDPDestroy(const VBOXSERVICEENV *pEnv, void *pInstance) 305 { 306 LogFlowFunc(("VBoxVRDPDestroy\n")); 307 VBOXVRDPCONTEXT *pCtx = (VBOXVRDPCONTEXT *)pInstance; 308 static DECLCALLBACK(void) VBoxVRDPDestroy(void *pInstance) 309 { 310 AssertPtrReturnVoid(pInstance); 311 312 LogFlowFuncEnter(); 313 314 PVBOXVRDPCONTEXT pCtx = (PVBOXVRDPCONTEXT)pInstance; 315 308 316 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 314 323 return; 315 324 } … … 318 327 * Thread function to wait for and process mode change requests 319 328 */ 320 unsigned __stdcall VBoxVRDPThread(void *pInstance) 321 { 322 VBOXVRDPCONTEXT *pCtx = (VBOXVRDPCONTEXT *)pInstance; 329 static 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 323 344 HANDLE gVBoxDriver = pCtx->pEnv->hDriver; 324 345 bool fTerminate = false; … … 328 349 maskInfo.u32OrMask = VMMDEV_EVENT_VRDP; 329 350 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 (;;) 341 361 { 342 362 /* wait for the event */ … … 346 366 if (DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent), &waitEvent, sizeof(waitEvent), &cbReturned, NULL)) 347 367 { 348 LogFlowFunc(("DeviceIOControl succeeded\n"));349 350 368 /* are we supposed to stop? */ 351 if ( WaitForSingleObject(pCtx->pEnv->hStopEvent, 0) == WAIT_OBJECT_0)369 if (*pfShutdown) 352 370 break; 353 354 LogFlowFunc(("checking event\n"));355 371 356 372 /* did we get the right event? */ … … 417 433 else 418 434 { 419 #ifndef DEBUG_andy /* Too noisy for me. */420 LogFlowFunc(("Error from DeviceIoControl VBOXGUEST_IOCTL_VMMREQUEST\n"));421 #endif422 435 /* 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) 426 439 break; 427 }428 440 } 429 441 } … … 431 443 else 432 444 { 433 #ifndef DEBUG_andy434 LogFlowFunc(("Error from DeviceIoControl VBOXGUEST_IOCTL_WAITEVENT\n"));435 #endif436 445 /* 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) 440 449 break; 441 }442 450 } 443 } while (!fTerminate);444 445 maskInfo.u32OrMask = 0;451 } 452 453 maskInfo.u32OrMask = 0; 446 454 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)) 453 456 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; 458 460 } 459 461 462 /** 463 * The service description. 464 */ 465 VBOXSERVICEDESC 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.