Changeset 62701 in vbox for trunk/src/VBox/Main/src-server/win/svcmain.cpp
- Timestamp:
- Jul 29, 2016 6:30:43 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/win/svcmain.cpp
r62679 r62701 41 41 #include <iprt/getopt.h> 42 42 #include <iprt/message.h> 43 #include <iprt\asm.h> 43 44 44 45 class CExeModule : public ATL::CComModule … … 50 51 void MonitorShutdown(); 51 52 bool StartMonitor(); 53 bool HasActiveConnection(); 52 54 bool bActivity; 53 55 }; 54 56 55 const DWORD dwTimeOut = 5000; /* time for EXE to be idle before shutting down */ 56 const DWORD dwPause = 100; /* time to wait for threads to finish up */ 57 /* Normal timeout usually used in Shutdown Monitor */ 58 const DWORD dwNormalTimeout = 5000; 59 volatile uint32_t dwTimeOut = dwNormalTimeout; /* time for EXE to be idle before shutting down. Can be decreased at system shutdown phase. */ 57 60 58 61 /* Passed to CreateThread to monitor the shutdown event */ … … 73 76 } 74 77 return l; 78 } 79 80 bool CExeModule::HasActiveConnection() 81 { 82 return bActivity || GetLockCount() > 0; 75 83 } 76 84 … … 88 96 } while (dwWait == WAIT_OBJECT_0); 89 97 /* timed out */ 90 if (! bActivity && GetLockCount() == 0) /* if no activity let's really bail */98 if (!HasActiveConnection()) /* if no activity let's really bail */ 91 99 { 92 100 /* Disable log rotation at this point, worst case a log file … … 112 120 #if _WIN32_WINNT >= 0x0400 113 121 CoSuspendClassObjects(); 114 if (! bActivity && GetLockCount() == 0)122 if (!HasActiveConnection()) 115 123 #endif 116 124 break; … … 135 143 OBJECT_ENTRY(CLSID_VirtualBox, VirtualBox) 136 144 END_OBJECT_MAP() 145 146 CExeModule _Module; 147 HWND g_hMainWindow = NULL; 148 HINSTANCE g_hInstance = NULL; 149 #define MAIN_WND_CLASS L"VirtualBox Interface" 150 151 /* 152 * Wrapper for Win API function ShutdownBlockReasonCreate 153 * This function defined starting from Vista only. 154 */ 155 BOOL ShutdownBlockReasonCreateAPI(HWND hWnd,LPCWSTR pwszReason) 156 { 157 BOOL result = FALSE; 158 typedef BOOL(WINAPI *PFNSHUTDOWNBLOCKREASONCREATE)(HWND hWnd, LPCWSTR pwszReason); 159 160 PFNSHUTDOWNBLOCKREASONCREATE pfn = (PFNSHUTDOWNBLOCKREASONCREATE)GetProcAddress( 161 GetModuleHandle(L"User32.dll"), "ShutdownBlockReasonCreate"); 162 _ASSERTE(pfn); 163 if (pfn) 164 result = pfn(hWnd, pwszReason); 165 return result; 166 } 167 168 /* 169 * Wrapper for Win API function ShutdownBlockReasonDestroy 170 * This function defined starting from Vista only. 171 */ 172 BOOL ShutdownBlockReasonDestroyAPI(HWND hWnd) 173 { 174 BOOL result = FALSE; 175 typedef BOOL(WINAPI *PFNSHUTDOWNBLOCKREASONDESTROY)(HWND hWnd); 176 177 PFNSHUTDOWNBLOCKREASONDESTROY pfn = (PFNSHUTDOWNBLOCKREASONDESTROY)GetProcAddress( 178 GetModuleHandle(L"User32.dll"), "ShutdownBlockReasonDestroy"); 179 _ASSERTE(pfn); 180 if (pfn) 181 result = pfn(hWnd); 182 return result; 183 } 184 185 186 LRESULT CALLBACK WinMainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 187 { 188 LRESULT rc = 0; 189 switch (msg) 190 { 191 case WM_QUERYENDSESSION: 192 { 193 rc = !_Module.HasActiveConnection(); 194 if (!rc) 195 { 196 /* place the VBoxSVC into system shutdown list */ 197 ShutdownBlockReasonCreateAPI(hwnd, L"Has active connections."); 198 /* decrease a latency of MonitorShutdown loop */ 199 ASMAtomicXchgU32(&dwTimeOut, 100); 200 Log(("VBoxSVCWinMain: VBoxSvc has active connections. bActivity = %d. Loc count = %d\n", 201 _Module.bActivity, _Module.GetLockCount())); 202 } 203 Log(("VBoxSVCWinMain: WM_QUERYENDSESSION msg: %d rc= %d\n", msg, rc)); 204 } break; 205 case WM_ENDSESSION: 206 { 207 /* Restore timeout of Monitor Shutdown if user canceled system shutdown */ 208 if (wParam == FALSE) 209 { 210 ASMAtomicXchgU32(&dwTimeOut, dwNormalTimeout); 211 Log(("VBoxSVCWinMain: user canceled system shutdown.\n")); 212 } 213 Log(("VBoxSVCWinMain: WM_ENDSESSION msg: %d. wParam: %d. lParam: %d\n", msg, wParam, lParam)); 214 } break; 215 case WM_DESTROY: 216 { 217 Log(("VBoxSVCWinMain: WM_DESTROY \n")); 218 ShutdownBlockReasonDestroyAPI(hwnd); 219 PostQuitMessage(0); 220 } break; 221 222 default: 223 { 224 Log(("VBoxSVCWinMain: msg %p\n", msg)); 225 rc = DefWindowProc(hwnd, msg, wParam, lParam); 226 } 227 } 228 return rc; 229 } 230 231 232 int CreateMainWindow() 233 { 234 int rc = VINF_SUCCESS; 235 _ASSERTE(g_hMainWindow == NULL); 236 237 LogFlow(("CreateMainWindow\n")); 238 239 g_hInstance = (HINSTANCE)GetModuleHandle(NULL); 240 241 /* Register the Window Class. */ 242 WNDCLASS wc; 243 RT_ZERO(wc); 244 245 wc.style = CS_NOCLOSE; 246 wc.lpfnWndProc = WinMainWndProc; 247 wc.hInstance = g_hInstance; 248 wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1); 249 wc.lpszClassName = MAIN_WND_CLASS; 250 251 252 ATOM atomWindowClass = RegisterClass(&wc); 253 254 if (atomWindowClass == 0) 255 { 256 Log(("Failed to register main window class\n")); 257 rc = VERR_NOT_SUPPORTED; 258 } 259 else 260 { 261 /* Create the window. */ 262 g_hMainWindow = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, 263 MAIN_WND_CLASS, MAIN_WND_CLASS, 264 WS_POPUPWINDOW, 265 0, 0, 1, 1, NULL, NULL, g_hInstance, NULL); 266 267 if (g_hMainWindow == NULL) 268 { 269 Log(("Failed to create main window\n")); 270 rc = VERR_NOT_SUPPORTED; 271 } 272 else 273 { 274 SetWindowPos(g_hMainWindow, HWND_TOPMOST, -200, -200, 0, 0, 275 SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE); 276 277 } 278 } 279 return 0; 280 } 281 282 283 void DestroyMainWindow() 284 { 285 _ASSERTE(g_hMainWindow != NULL); 286 Log(("SVCMain: DestroyMainWindow \n")); 287 if (g_hMainWindow != NULL) 288 { 289 DestroyWindow(g_hMainWindow); 290 g_hMainWindow = NULL; 291 292 if (g_hInstance != NULL) 293 { 294 UnregisterClass(MAIN_WND_CLASS, g_hInstance); 295 g_hInstance = NULL; 296 } 297 } 298 } 137 299 138 300 … … 172 334 */ 173 335 RTR3InitExe(argc, &argv, 0); 174 CExeModule _Module; 336 175 337 176 338 /* Note that all options are given lowercase/camel case/uppercase to … … 395 557 _ASSERTE(SUCCEEDED(hRes)); 396 558 559 if (RT_SUCCESS(CreateMainWindow())) 560 { 561 Log(("SVCMain: Main window succesfully created\n")); 562 } 563 else 564 { 565 Log(("SVCMain: Failed to create main window\n")); 566 } 567 397 568 MSG msg; 398 while (GetMessage(&msg, 0, 0, 0)) 569 while (GetMessage(&msg, 0, 0, 0) > 0) 570 { 399 571 DispatchMessage(&msg); 572 TranslateMessage(&msg); 573 } 574 575 DestroyMainWindow(); 400 576 401 577 _Module.RevokeClassObjects(); 402 Sleep(dwPause); //wait for any threads to finish403 578 } 404 579
Note:
See TracChangeset
for help on using the changeset viewer.