Changeset 53035 in vbox
- Timestamp:
- Oct 11, 2014 2:50:10 AM (10 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/err.h
r53017 r53035 2530 2530 * got potentially fatally buggy anti-virus software installed.) */ 2531 2531 #define VERR_SUP_VP_REPLACE_VIRTUAL_MEMORY_FAILED (-5673) 2532 /** Error getting the file mode. */ 2533 #define VERR_SUP_VP_FILE_MODE_ERROR (-5674) 2534 /** Error creating an event semaphore for used with asynchronous reads. */ 2535 #define VERR_SUP_VP_CREATE_READ_EVT_SEM_FAILED (-5675) 2532 2536 2533 2537 /** @} */ -
trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h
r53022 r53035 93 93 /** The core reader structure. */ 94 94 RTLDRREADER Core; 95 /** The file handle 95 /** The file handle. */ 96 96 HANDLE hFile; 97 /** Handle to event sempahore in case we're force to deal with asynchronous 98 * I/O. */ 99 HANDLE hEvent; 97 100 /** Current file offset. */ 98 101 RTFOFF off; -
trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp
r53034 r53035 211 211 PSUPHNTVIRDR pNtViRdr = (PSUPHNTVIRDR)pReader; 212 212 Assert(pNtViRdr->Core.uMagic == RTLDRREADER_MAGIC); 213 213 NTSTATUS rcNt; 214 215 /* Check for type overflow (paranoia). */ 214 216 if ((ULONG)cb != cb) 215 217 return VERR_OUT_OF_RANGE; 216 218 217 218 /* 219 * For some reason I'm getting occational read error in an XP VM with 220 * STATUS_FAILED_DRIVER_ENTRY. Redoing the call again works in the 221 * debugger, so try do that automatically. 222 */ 223 for (uint32_t iTry = 0;; iTry++) 224 { 225 LARGE_INTEGER offNt; 226 offNt.QuadPart = off; 227 228 IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER; 229 NTSTATUS rcNt = NtReadFile(pNtViRdr->hFile, 230 NULL /*hEvent*/, 231 NULL /*ApcRoutine*/, 232 NULL /*ApcContext*/, 233 &Ios, 234 pvBuf, 235 (ULONG)cb, 236 &offNt, 237 NULL); 238 if (NT_SUCCESS(rcNt)) 239 rcNt = Ios.Status; 240 if (NT_SUCCESS(rcNt)) 219 #ifdef IN_RING3 220 /* Make sure the event semaphore is reset (normally we don't use one). */ 221 if (pNtViRdr->hEvent) 222 { 223 rcNt = NtClearEvent(pNtViRdr->hEvent); 224 if (!NT_SUCCESS(rcNt)) 225 return RTErrConvertFromNtStatus(rcNt); 226 } 227 #endif 228 229 /* Perform the read. */ 230 LARGE_INTEGER offNt; 231 offNt.QuadPart = off; 232 233 IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER; 234 rcNt = NtReadFile(pNtViRdr->hFile, 235 pNtViRdr->hEvent, 236 NULL /*ApcRoutine*/, 237 NULL /*ApcContext*/, 238 &Ios, 239 pvBuf, 240 (ULONG)cb, 241 &offNt, 242 NULL); 243 244 #ifdef IN_RING0 245 /* In ring-0 the handles shall be synchronized and not alertable. */ 246 AssertMsg(rcNt == STATUS_SUCCESS || !NT_SUCCESS(rcNt), ("%#x\n", rcNt)); 247 #else 248 /* In ring-3 we like our handles synchronized and non-alertable, but we 249 sometimes have to take what we can get. So, deal with pending I/O as 250 best we can. */ 251 if (rcNt == STATUS_PENDING) 252 rcNt = NtWaitForSingleObject(pNtViRdr->hEvent ? pNtViRdr->hEvent : pNtViRdr->hFile, FALSE /*Alertable*/, NULL); 253 #endif 254 if (NT_SUCCESS(rcNt)) 255 rcNt = Ios.Status; 256 if (NT_SUCCESS(rcNt)) 257 { 258 /* We require the caller to not read beyond the end of the file since 259 we don't have any way to communicate that we've read less that 260 requested. */ 261 if (Ios.Information == cb) 241 262 { 242 if (Ios.Information == cb) 243 { 244 pNtViRdr->off = off + cb; 245 return VINF_SUCCESS; 246 } 263 pNtViRdr->off = off + cb; /* (just for show) */ 264 return VINF_SUCCESS; 265 } 247 266 #ifdef IN_RING3 248 249 250 267 supR3HardenedError(VERR_READ_ERROR, false, 268 "supHardNtViRdrRead: Only got %#zx bytes when requesting %#zx bytes at %#llx in '%s'.\n", 269 Ios.Information, off, cb, pNtViRdr->szFilename); 251 270 #endif 252 pNtViRdr->off = -1; 253 return VERR_READ_ERROR; 254 } 255 256 /** @todo This nonsense is probably due to missing FILE_SYNCHRONOUS_IO_NONALERT 257 * flags in early code stage. Should clean this up, but leave code 258 * for handling STATUS_PENDING as we don't know what callers of 259 * NtCreateSection might've been passing to their NtCreateFile calls. 260 * In ring-0, this code is mostly pointless, I think. */ 261 /* 262 * Delay a little before we retry? 263 */ 264 #ifdef IN_RING3 265 if (iTry == 0) 266 NtYieldExecution(); 267 else if (iTry >= 1) 268 { 269 LARGE_INTEGER Time; 270 Time.QuadPart = -1000000 / 100; /* 1ms in 100ns units, relative time. */ 271 NtDelayExecution(TRUE, &Time); 272 } 273 #endif 274 /* 275 * Before we give up, we'll try split up the request in case the 276 * kernel is low on memory or similar. For simplicity reasons, we do 277 * this in a recursion fashion. 278 */ 279 if (iTry >= 2) 280 { 281 if (cb >= _8K) 282 { 283 size_t const cbBlock = RT_ALIGN_Z(cb / 4, 512); 284 while (cb > 0) 285 { 286 size_t cbThisRead = RT_MIN(cb, cbBlock); 287 int rc = supHardNtViRdrRead(&pNtViRdr->Core, pvBuf, cbThisRead, off); 288 if (RT_FAILURE(rc)) 289 return rc; 290 off += cbThisRead; 291 cb -= cbThisRead; 292 pvBuf = (uint8_t *)pvBuf + cbThisRead; 293 } 294 return VINF_SUCCESS; 295 } 296 297 #ifdef IN_RING3 298 supR3HardenedError(VERR_READ_ERROR, false, "supHardNtViRdrRead: Error %#x reading %#zx bytes at %#llx in '%s'.\n", 299 rcNt, off, cb, pNtViRdr->szFilename); 300 #endif 301 pNtViRdr->off = -1; 302 return VERR_READ_ERROR; 303 } 304 } 271 } 272 pNtViRdr->off = -1; 273 return VERR_READ_ERROR; 305 274 } 306 275 … … 354 323 pNtViRdr->Core.uMagic = ~RTLDRREADER_MAGIC; 355 324 pNtViRdr->hFile = NULL; 356 325 #ifdef IN_RING3 326 if (pNtViRdr->hEvent) 327 { 328 NtClose(pNtViRdr->hEvent); 329 pNtViRdr->hEvent = NULL; 330 } 331 #endif 357 332 RTMemFree(pNtViRdr); 358 333 return VINF_SUCCESS; … … 381 356 382 357 /* 358 * Figure the file mode so we can see whether we'll be needing an event 359 * semaphore for waiting on reads. This may happen in very unlikely 360 * NtCreateSection scenarios. 361 */ 362 #if defined(IN_RING3) || defined(VBOX_STRICT) 363 Ios.Status = STATUS_UNSUCCESSFUL; 364 ULONG fMode; 365 rcNt = NtQueryInformationFile(hFile, &Ios, &fMode, sizeof(fMode), FileModeInformation); 366 if (!NT_SUCCESS(rcNt) || !NT_SUCCESS(Ios.Status)) 367 return VERR_SUP_VP_FILE_MODE_ERROR; 368 #endif 369 370 HANDLE hEvent = NULL; 371 #ifdef IN_RING3 372 if (!(fMode & (FILE_SYNCHRONOUS_IO_NONALERT | FILE_SYNCHRONOUS_IO_ALERT))) 373 { 374 rcNt = NtCreateEvent(&hEvent, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE); 375 if (!NT_SUCCESS(rcNt)) 376 return VERR_SUP_VP_CREATE_READ_EVT_SEM_FAILED; 377 } 378 #else 379 Assert(fMode & FILE_SYNCHRONOUS_IO_NONALERT); 380 #endif 381 382 /* 383 383 * Calc the file name length and allocate memory for the reader instance. 384 384 */ … … 390 390 PSUPHNTVIRDR pNtViRdr = (PSUPHNTVIRDR)RTMemAllocZ(sizeof(*pNtViRdr) + cchFilename); 391 391 if (!pNtViRdr) 392 { 393 #ifdef IN_RING3 394 if (hEvent != NULL) 395 NtClose(hEvent); 396 #endif 392 397 return VERR_NO_MEMORY; 398 } 393 399 394 400 /* … … 413 419 pNtViRdr->Core.pfnDestroy = supHardNtViRdrDestroy; 414 420 pNtViRdr->hFile = hFile; 421 pNtViRdr->hEvent = hEvent; 415 422 pNtViRdr->off = 0; 416 423 pNtViRdr->cbFile = StdInfo.EndOfFile.QuadPart;
Note:
See TracChangeset
for help on using the changeset viewer.