Changeset 39760 in vbox for trunk/src/VBox/Additions/common
- Timestamp:
- Jan 12, 2012 2:30:32 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp
r39592 r39760 30 30 31 31 #include <iprt/assert.h> 32 #include <iprt/ldr.h> 32 33 #include <iprt/mem.h> 33 34 #include <iprt/thread.h> … … 72 73 * Prototypes 73 74 *******************************************************************************/ 74 uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, VBOXSERVICEVMINFOPROC const *paProcs, DWORD cProcs);75 uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, PVBOXSERVICEVMINFOPROC const paProcs, DWORD cProcs); 75 76 bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER a_pUserInfo, PLUID a_pSession); 76 77 int VBoxServiceVMInfoWinProcessesEnumerate(PVBOXSERVICEVMINFOPROC *ppProc, DWORD *pdwCount); 77 78 void VBoxServiceVMInfoWinProcessesFree(PVBOXSERVICEVMINFOPROC paProcs); 78 79 80 typedef BOOL WINAPI FNQUERYFULLPROCESSIMAGENAME(HANDLE, DWORD, LPTSTR, PDWORD); 81 typedef FNQUERYFULLPROCESSIMAGENAME *PFNQUERYFULLPROCESSIMAGENAME; 79 82 80 83 81 84 #ifndef TARGET_NT4 85 86 /** 87 * Retrieves the module name of a given process. 88 * 89 * @return IPRT status code. 90 * @param pProc 91 * @param pszBuf 92 * @param cbBuf 93 */ 94 static int VBoxServiceVMInfoWinProcessesGetModuleName(PVBOXSERVICEVMINFOPROC const pProc, 95 TCHAR *pszName, size_t cbName) 96 { 97 AssertPtrReturn(pProc, VERR_INVALID_POINTER); 98 AssertPtrReturn(pszName, VERR_INVALID_POINTER); 99 AssertReturn(cbName, VERR_INVALID_PARAMETER); 100 101 OSVERSIONINFOEX OSInfoEx; 102 RT_ZERO(OSInfoEx); 103 OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); 104 if ( !GetVersionEx((LPOSVERSIONINFO) &OSInfoEx) 105 || OSInfoEx.dwPlatformId != VER_PLATFORM_WIN32_NT) 106 { 107 /* Platform other than NT (e.g. Win9x) not supported. */ 108 return VERR_NOT_SUPPORTED; 109 } 110 111 int rc = VINF_SUCCESS; 112 113 DWORD dwFlags = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ; 114 if (OSInfoEx.dwMajorVersion >= 6 /* Vista or later */) 115 dwFlags = 0x1000; /* = PROCESS_QUERY_LIMITED_INFORMATION; less privileges needed. */ 116 117 HANDLE h = OpenProcess(dwFlags, FALSE, pProc->id); 118 if (h == NULL) 119 { 120 DWORD dwErr = GetLastError(); 121 if (g_cVerbosity) 122 VBoxServiceError("VMInfo/Users: Unable to open process with PID=%ld, error=%ld", 123 pProc->id, dwErr); 124 rc = RTErrConvertFromWin32(dwErr); 125 } 126 else 127 { 128 /* Since GetModuleFileNameEx has trouble with cross-bitness stuff (32-bit apps cannot query 64-bit 129 apps and vice verse) we have to use a different code path for Vista and up. */ 130 131 /* Note: For 2000 + NT4 we might just use GetModuleFileName() instead. */ 132 if (OSInfoEx.dwMajorVersion >= 6 /* Vista or later */) 133 { 134 /* Loading the module and getting the symbol for each and every process is expensive 135 * -- since this function (at the moment) only is used for debugging purposes it's okay. */ 136 RTLDRMOD hMod; 137 rc = RTLdrLoad("kernel32.dll", &hMod); 138 if (RT_SUCCESS(rc)) 139 { 140 PFNQUERYFULLPROCESSIMAGENAME pfnQueryFullProcessImageName; 141 rc = RTLdrGetSymbol(hMod, "QueryFullProcessImageNameA", (void **)&pfnQueryFullProcessImageName); 142 if (RT_SUCCESS(rc)) 143 { 144 DWORD dwLen = sizeof(pszName); 145 if (!pfnQueryFullProcessImageName(h, 0 /*PROCESS_NAME_NATIVE*/, pszName, &dwLen)) 146 rc = VERR_ACCESS_DENIED; 147 } 148 149 RTLdrClose(hMod); 150 } 151 } 152 else 153 { 154 if (!GetModuleFileNameEx(h, NULL /* Get main executable */, pszName, cbName / sizeof(TCHAR))) 155 rc = VERR_ACCESS_DENIED; 156 } 157 158 if (VERR_ACCESS_DENIED == rc) 159 { 160 DWORD dwErr = GetLastError(); 161 if (g_cVerbosity) 162 VBoxServiceError("VMInfo/Users: Unable to retrieve module name for PID=%ld, error=%ld", 163 pProc->id, dwErr); 164 rc = RTErrConvertFromWin32(dwErr); 165 } 166 167 CloseHandle(h); 168 } 169 170 return rc; 171 } 172 82 173 83 174 /** … … 91 182 TOKEN_INFORMATION_CLASS tkClass) 92 183 { 93 AssertPtr (pProc);184 AssertPtrReturn(pProc, VERR_INVALID_POINTER); 94 185 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pProc->id); 95 186 if (h == NULL) 96 return RTErrConvertFromWin32(GetLastError()); 187 { 188 DWORD dwErr = GetLastError(); 189 if (g_cVerbosity) 190 VBoxServiceError("VMInfo/Users: Unable to open process with PID=%ld, error=%ld", 191 pProc->id, dwErr); 192 return RTErrConvertFromWin32(dwErr); 193 } 97 194 98 195 int rc = VERR_NO_MEMORY; … … 145 242 } 146 243 else 147 rc = RTErrConvertFromWin32(GetLastError()); 244 { 245 DWORD dwErr = GetLastError(); 246 if (g_cVerbosity) 247 VBoxServiceError("VMInfo/Users: Unable to query process token for PID=%ld, error=%ld\n", 248 pProc->id, dwErr); 249 rc = RTErrConvertFromWin32(dwErr); 250 } 148 251 CloseHandle(h); 149 252 return rc; … … 171 274 */ 172 275 DWORD cProcesses = 64; 173 PDWORD paP ids= NULL;276 PDWORD paPID = NULL; 174 277 int rc = VINF_SUCCESS; 175 278 do … … 177 280 /* Allocate / grow the buffer first. */ 178 281 cProcesses *= 2; 179 void *pvNew = RTMemRealloc(paP ids, cProcesses * sizeof(DWORD));282 void *pvNew = RTMemRealloc(paPID, cProcesses * sizeof(DWORD)); 180 283 if (!pvNew) 181 284 { … … 183 286 break; 184 287 } 185 paP ids= (PDWORD)pvNew;288 paPID = (PDWORD)pvNew; 186 289 187 290 /* Query the processes. Not the cbRet == buffer size means there could be more work to be done. */ 188 291 DWORD cbRet; 189 if (!EnumProcesses(paP ids, cProcesses * sizeof(DWORD), &cbRet))292 if (!EnumProcesses(paPID, cProcesses * sizeof(DWORD), &cbRet)) 190 293 { 191 294 rc = RTErrConvertFromWin32(GetLastError()); … … 197 300 break; 198 301 } 199 } while (cProcesses <= 32768); /* Should be enough; see: http://blogs.technet.com/markrussinovich/archive/2009/07/08/3261309.aspx */302 } while (cProcesses <= _32K); /* Should be enough; see: http://blogs.technet.com/markrussinovich/archive/2009/07/08/3261309.aspx */ 200 303 if (RT_SUCCESS(rc)) 201 304 { … … 210 313 for (DWORD i = 0; i < cProcesses; i++) 211 314 { 212 paProcs[i].id = paP ids[i];315 paProcs[i].id = paPID[i]; 213 316 rc = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenStatistics); 214 317 if (RT_FAILURE(rc)) … … 233 336 } 234 337 235 RTMemFree(paP ids);338 RTMemFree(paPID); 236 339 return rc; 237 340 } … … 256 359 * @param cProcs The number of processes in the snaphot. 257 360 */ 258 uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, VBOXSERVICEVMINFOPROC const *paProcs, DWORD cProcs)361 uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, PVBOXSERVICEVMINFOPROC const paProcs, DWORD cProcs) 259 362 { 260 363 if (!pSession) … … 287 390 { 288 391 cNumProcs++; 289 if ( g_cVerbosity < 4) /* We want a bit more info on highverbosity. */392 if (!g_cVerbosity) /* We want a bit more info on higher verbosity. */ 290 393 break; 291 } 292 } 293 294 if (g_cVerbosity >= 4) 394 395 TCHAR szModule[_1K]; 396 int rc2 = VBoxServiceVMInfoWinProcessesGetModuleName(&paProcs[i], szModule, sizeof(szModule)); 397 if (RT_SUCCESS(rc2)) 398 VBoxServiceVerbose(4, "VMInfo/Users: PID=%ld: %s\n", 399 paProcs[i].id, szModule); 400 } 401 } 402 403 if (g_cVerbosity) 295 404 VBoxServiceVerbose(3, "VMInfo/Users: Session %u has %u processes\n", 296 405 pSessionData->Session, cNumProcs);
Note:
See TracChangeset
for help on using the changeset viewer.