Changeset 89095 in vbox for trunk/src/VBox/Frontends
- Timestamp:
- May 17, 2021 12:55:55 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp
r89017 r89095 37 37 #include <iprt/initterm.h> 38 38 #include <iprt/message.h> 39 #include <iprt/semaphore.h> 39 40 #include <iprt/path.h> 40 41 #include <iprt/stream.h> … … 750 751 751 752 #endif /* RT_OS_DARWIN */ 753 754 755 #ifdef RT_OS_WINDOWS 756 757 #define MAIN_WND_CLASS L"VirtualBox Headless Interface" 758 759 HINSTANCE g_hInstance = NULL; 760 HWND g_hWindow = NULL; 761 RTSEMEVENT g_hCanQuit; 762 763 static DECLCALLBACK(int) windowsMessageMonitor(RTTHREAD ThreadSelf, void *pvUser); 764 static int createWindow(); 765 static LRESULT CALLBACK WinMainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); 766 static void destroyWindow(); 767 768 769 static DECLCALLBACK(int) 770 windowsMessageMonitor(RTTHREAD ThreadSelf, void *pvUser) 771 { 772 RT_NOREF(ThreadSelf, pvUser); 773 int rc; 774 775 rc = createWindow(); 776 if (RT_FAILURE(rc)) 777 return rc; 778 779 RTSemEventCreate(&g_hCanQuit); 780 781 MSG msg; 782 BOOL b; 783 while ((b = ::GetMessage(&msg, 0, 0, 0)) > 0) 784 { 785 ::TranslateMessage(&msg); 786 ::DispatchMessage(&msg); 787 } 788 789 if (b < 0) 790 LogRel(("VBoxHeadless: GetMessage failed\n")); 791 LogRel(("VBoxHeadless: stopping windows message loop\n")); 792 793 destroyWindow(); 794 return VINF_SUCCESS; 795 } 796 797 798 static int 799 createWindow() 800 { 801 /* program instance handle */ 802 g_hInstance = (HINSTANCE)::GetModuleHandle(NULL); 803 if (g_hInstance == NULL) 804 { 805 LogRel(("VBoxHeadless: failed to obtain module handle\n")); 806 return VERR_GENERAL_FAILURE; 807 } 808 809 /* window class */ 810 WNDCLASS wc; 811 RT_ZERO(wc); 812 813 wc.style = CS_NOCLOSE; 814 wc.lpfnWndProc = WinMainWndProc; 815 wc.hInstance = g_hInstance; 816 wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1); 817 wc.lpszClassName = MAIN_WND_CLASS; 818 819 ATOM atomWindowClass = ::RegisterClass(&wc); 820 if (atomWindowClass == 0) 821 { 822 LogRel(("VBoxHeadless: failed to register window class\n")); 823 return VERR_GENERAL_FAILURE; 824 } 825 826 /* secret window, secret garden */ 827 g_hWindow = ::CreateWindowEx(0, MAIN_WND_CLASS, MAIN_WND_CLASS, 0, 828 0, 0, 1, 1, NULL, NULL, g_hInstance, NULL); 829 if (g_hWindow == NULL) 830 { 831 LogRel(("VBoxHeadless: failed to create window\n")); 832 return VERR_GENERAL_FAILURE; 833 } 834 835 return VINF_SUCCESS; 836 } 837 838 839 static void 840 destroyWindow() 841 { 842 if (g_hWindow == NULL) 843 return; 844 845 ::DestroyWindow(g_hWindow); 846 g_hWindow = NULL; 847 848 if (g_hInstance == NULL) 849 return; 850 851 ::UnregisterClass(MAIN_WND_CLASS, g_hInstance); 852 g_hInstance = NULL; 853 } 854 855 856 static LRESULT CALLBACK 857 WinMainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 858 { 859 int rc; 860 861 LRESULT lResult = 0; 862 switch (msg) 863 { 864 case WM_QUERYENDSESSION: 865 if (lParam != 0) 866 LogRel(("VBoxHeadless: WM_QUERYENDSESSION (0x%08lx)\n", (unsigned long)lParam)); 867 else 868 LogRel(("VBoxHeadless: WM_QUERYENDSESSION\n")); 869 870 /* tell the user what we are doing */ 871 ::ShutdownBlockReasonCreate(hwnd, L"Waiting for VM to terminate"); 872 873 /* tell the VM to save state/power off */ 874 g_fTerminateFE = true; 875 gEventQ->interruptEventQueueProcessing(); 876 877 /* do not block windows session termination */ 878 lResult = TRUE; 879 break; 880 881 case WM_ENDSESSION: 882 if (g_hCanQuit != NIL_RTSEMEVENT) 883 { 884 LogRel(("VBoxHeadless: WM_ENDSESSION: waiting for VM termination...\n")); 885 886 rc = RTSemEventWait(g_hCanQuit, RT_INDEFINITE_WAIT); 887 if (RT_SUCCESS(rc)) 888 LogRel(("VBoxHeadless: WM_ENDSESSION: done\n")); 889 else 890 LogRel(("VBoxHeadless: WM_ENDSESSION: failed to wait for VM termination: %Rrc\n", rc)); 891 } 892 else 893 { 894 LogRel(("VBoxHeadless: WM_ENDSESSION: cannot wait for VM termination\n")); 895 } 896 lResult = TRUE; 897 break; 898 899 default: 900 lResult = ::DefWindowProc(hwnd, msg, wParam, lParam); 901 break; 902 } 903 return lResult; 904 } 905 #endif /* RT_OS_WINDOWS */ 752 906 753 907 … … 1075 1229 1076 1230 HRESULT rc; 1231 int irc; 1077 1232 1078 1233 rc = com::Initialize(); … … 1419 1574 #endif 1420 1575 1576 #ifdef RT_OS_WINDOWS 1577 /* 1578 * Spawn windows message pump to monitor session events. 1579 */ 1580 RTTHREAD hThrMsg; 1581 irc = RTThreadCreate(&hThrMsg, 1582 windowsMessageMonitor, NULL, 1583 0, /* :cbStack */ 1584 RTTHREADTYPE_MSG_PUMP, 0, 1585 "MSG"); 1586 if (RT_FAILURE(irc)) /* not fatal */ 1587 LogRel(("VBoxHeadless: failed to start windows message monitor: %Rrc\n", irc)); 1588 #endif /* RT_OS_WINDOWS */ 1589 1421 1590 1422 1591 /* … … 1426 1595 for (;;) 1427 1596 { 1428 i nt irc = gEventQ->processEventQueue(RT_INDEFINITE_WAIT);1597 irc = gEventQ->processEventQueue(RT_INDEFINITE_WAIT); 1429 1598 1430 1599 /* … … 1567 1736 com::Shutdown(); 1568 1737 1569 LogFlow(("VBoxHeadless FINISHED.\n")); 1570 1738 #ifdef RT_OS_WINDOWS 1739 /* tell the session monitor it can ack WM_ENDSESSION */ 1740 if (g_hCanQuit != NIL_RTSEMEVENT) 1741 { 1742 RTSemEventSignal(g_hCanQuit); 1743 } 1744 1745 /* tell the session monitor to quit */ 1746 if (g_hWindow != NULL) 1747 { 1748 ::PostMessage(g_hWindow, WM_QUIT, 0, 0); 1749 } 1750 #endif 1751 1752 LogRel(("VBoxHeadless: exiting\n")); 1571 1753 return FAILED(rc) ? 1 : 0; 1572 1754 }
Note:
See TracChangeset
for help on using the changeset viewer.