Changeset 71139 in vbox for trunk/src/VBox/Main/src-server/win
- Timestamp:
- Feb 27, 2018 5:48:13 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 121027
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/win/svcmain.cpp
r70030 r71139 28 28 #include "VBox/com/com.h" 29 29 #include "VBox/com/VirtualBox.h" 30 #include "VBox/com/array.h" 30 31 31 32 #include "VirtualBoxImpl.h" … … 44 45 #include <iprt/asm.h> 45 46 47 #include <TlHelp32.h> 46 48 47 49 /********************************************************************************************************************************* … … 94 96 volatile uint32_t dwTimeOut = dwNormalTimeout; /* time for EXE to be idle before shutting down. Can be decreased at system shutdown phase. */ 95 97 98 99 BOOL CALLBACK CloseWindowProc(_In_ HWND hWnd, _In_ LPARAM /* lParam */) 100 { 101 _ASSERTE(hWnd); 102 DWORD_PTR dwResult; 103 // Close topmost windows in the thread 104 LRESULT lResult = SendMessageTimeout(hWnd, WM_CLOSE, NULL, NULL, 105 SMTO_ABORTIFHUNG | SMTO_BLOCK, 0, &dwResult); 106 if (lResult != 0) 107 { 108 LogRel(("EnumThreadWndProc: Close message sent to window %x successfully \n", hWnd)); 109 } 110 else 111 { 112 LogRel(("EnumThreadWndProc: Cannot send event to window %x. result: %d, last error: %x\n", 113 hWnd, dwResult, GetLastError())); 114 } 115 return TRUE; 116 } 117 118 void SendCloseToAllThreads(DWORD dwTargetPid) 119 { 120 HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); 121 if (hSnapshot == NULL) 122 { 123 LogRel(("SendCloseToAllThreads: cannot get threads snapshot. error: 0x%x \n", 124 GetLastError())); 125 return; 126 } 127 128 THREADENTRY32 threadEntry; 129 ZeroMemory(&threadEntry, sizeof(threadEntry)); 130 threadEntry.dwSize = sizeof(threadEntry); 131 132 if (Thread32First(hSnapshot, &threadEntry)) 133 { 134 do 135 { 136 LogRel(("SendCloseToAllThreads: process: %d thread: %x \n", 137 threadEntry.th32OwnerProcessID, threadEntry.th32ThreadID)); 138 if (threadEntry.th32OwnerProcessID == dwTargetPid) 139 { 140 BOOL bRes = EnumThreadWindows(threadEntry.th32ThreadID, CloseWindowProc, NULL); 141 if (!bRes) 142 { 143 LogRel(("SendCloseToAllThreads: EnumThreadWindows() failed to enumerate threads. error: %x \n", 144 GetLastError())); 145 } 146 else 147 { 148 LogRel(("SendCloseToAllThreads: about to close window in thread %x of process d\n", 149 threadEntry.th32ThreadID, dwTargetPid)); 150 } 151 } 152 } while (Thread32Next(hSnapshot, &threadEntry)); 153 } 154 CloseHandle(hSnapshot); 155 } 156 157 static int CloseActiveClients() 158 { 159 ComPtr<IVirtualBoxClientList> ptrClientList; 160 /* 161 * Connect to VBoxSDS. 162 */ 163 // TODO: here we close all API client processes: our own and customers 164 LogRelFunc(("Forcibly close API clients during system shutdown on Windows 7:\n")); 165 HRESULT hrc = CoCreateInstance(CLSID_VirtualBoxClientList, NULL, CLSCTX_LOCAL_SERVER, IID_IVirtualBoxClientList, 166 (void **)ptrClientList.asOutParam()); 167 if (SUCCEEDED(hrc)) 168 { 169 com::SafeArray<LONG> aCllients; 170 hrc = ptrClientList->get_Clients(aCllients.__asOutParam()); 171 RTCList<LONG> clientsList = aCllients.toList(); 172 LogRel(("==========Client list begin ========\n")); 173 for (int i = 0; i < clientsList.size(); i++) 174 { 175 LogRel(("About to close client pid: %d\n", clientsList[i])); 176 SendCloseToAllThreads(clientsList[i]); 177 } 178 LogRel(("==========Client list end ========\n")); 179 } 180 else 181 { 182 LogFunc(("Error to connect to VBoxSDS: hr=%Rhrf\n", hrc)); 183 } 184 return 0; 185 } 186 187 // These are copies of functions defined in VersionHelpers.h 188 bool IsWindowsVersionOrGreaterWrap(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) 189 { 190 OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 }; 191 DWORDLONG const dwlConditionMask = VerSetConditionMask( 192 VerSetConditionMask( 193 VerSetConditionMask( 194 0, VER_MAJORVERSION, VER_GREATER_EQUAL), 195 VER_MINORVERSION, VER_GREATER_EQUAL), 196 VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); 197 198 osvi.dwMajorVersion = wMajorVersion; 199 osvi.dwMinorVersion = wMinorVersion; 200 osvi.wServicePackMajor = wServicePackMajor; 201 202 return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; 203 } 204 205 206 #if !defined _WIN32_WINNT_WIN8 207 208 #define _WIN32_WINNT_WIN8 0x0602 209 210 #endif // #if !defined _WIN32_WINNT_WIN8 211 212 bool IsWindows8OrGreaterWrap() 213 { 214 return IsWindowsVersionOrGreaterWrap(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0); 215 } 96 216 97 217 … … 241 361 HRESULT VirtualBoxClassFactory::i_registerWithSds(IUnknown **ppOtherVirtualBox); 242 362 void VirtualBoxClassFactory::i_deregisterWithSds(void); 363 void VirtualBoxClassFactory::i_finishVBoxSvc(); 243 364 244 365 friend VBoxSVCRegistration; … … 311 432 return m_pFactory->i_getVirtualBox(ppResult); 312 433 return E_FAIL; 434 } 435 436 // IVBoxSVCRegistration: called from 437 STDMETHOD(NotifyClientsFinished)() 438 { 439 LogRelFunc(("All clients gone - shutdown sequence initiated\n")); 440 441 m_pFactory->i_finishVBoxSvc(); 442 443 // This is not enough to finish VBoxSvc such as reference to crashed client still is in action 444 // So I forcebly shutdown VBoxSvc 445 while (g_pModule->Unlock() > 0) 446 {}; 447 448 return S_OK; 313 449 } 314 450 }; … … 354 490 NOREF(hrc); 355 491 } 356 m_ptrVirtualBoxSDS.setNull(); 357 g_fRegisteredWithVBoxSDS = false; 358 } 359 if (m_pVBoxSVC) 360 { 361 m_pVBoxSVC->m_pFactory = NULL; 362 m_pVBoxSVC->Release(); 363 m_pVBoxSVC = NULL; 364 } 492 } 493 i_finishVBoxSvc(); 365 494 } 366 495 … … 381 510 Log(("VirtualBoxClassFactory::GetVirtualBox: E_FAIL\n")); 382 511 return E_FAIL; 512 } 513 514 515 void VirtualBoxClassFactory::i_finishVBoxSvc() 516 { 517 LogRelFunc(("Finish work of VBoxSVc and VBoxSDS\n")); 518 if (m_ptrVirtualBoxSDS.isNotNull()) 519 { 520 m_ptrVirtualBoxSDS.setNull(); 521 g_fRegisteredWithVBoxSDS = false; 522 } 523 if (m_pVBoxSVC) 524 { 525 m_pVBoxSVC->m_pFactory = NULL; 526 m_pVBoxSVC->Release(); 527 m_pVBoxSVC = NULL; 528 } 383 529 } 384 530 … … 536 682 Log(("VBoxSVCWinMain: WM_QUERYENDSESSION: VBoxSvc has active connections. bActivity = %d. Loc count = %d\n", 537 683 g_pModule->bActivity, g_pModule->GetLockCount())); 684 685 // On Windows 7 our clients doesn't receive right sequence of Session End events 686 // So we send them all WM_QUIT to forcible close them. 687 // Windows 10 sends end session events correctly 688 // Note: the IsWindows8Point1() and IsWindows10OrGreater() doesnt work in 689 // application without manifest so I use old compatible functions for detection of Win 7 690 if(!IsWindows8OrGreaterWrap()) 691 CloseActiveClients(); 538 692 } 539 693 rc = !fActiveConnection; … … 629 783 } 630 784 } 785 } 786 787 788 int SetServiceEnvFlag() 789 { 790 int rc = VINF_SUCCESS; 791 if (!SetEnvironmentVariable(L"VBOX_SERVICE_PROCESS", L"")) 792 { 793 rc = RTErrConvertFromWin32(GetLastError()); 794 LogRel(("Error: cannot set service environment flag: %Rrs\n", rc)); 795 } 796 return rc; 631 797 } 632 798 … … 667 833 */ 668 834 RTR3InitExe(argc, &argv, 0); 835 836 SetServiceEnvFlag(); 669 837 670 838 static const RTGETOPTDEF s_aOptions[] = … … 873 1041 if (RT_FAILURE(vrc)) 874 1042 { 875 Log(("SVCMAIN: Failed to process Helper request (%Rrc). ", vrc));1043 Log(("SVCMAIN: Failed to process Helper request (%Rrc).\n", vrc)); 876 1044 nRet = 1; 877 1045 }
Note:
See TracChangeset
for help on using the changeset viewer.