Changeset 71136 in vbox for trunk/src/VBox/HostDrivers/Support
- Timestamp:
- Feb 27, 2018 1:17:36 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 121023
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp
r71075 r71136 231 231 { "SUPR0TracerUmodProbeFire", (void *)(uintptr_t)SUPR0TracerUmodProbeFire }, 232 232 { "SUPR0UnlockMem", (void *)(uintptr_t)SUPR0UnlockMem }, 233 #ifdef RT_OS_WINDOWS 234 { "SUPR0IoCtlSetupForHandle", (void *)(uintptr_t)SUPR0IoCtlSetupForHandle }, /* only-windows */ 235 { "SUPR0IoCtlPerform", (void *)(uintptr_t)SUPR0IoCtlPerform }, /* only-windows */ 236 { "SUPR0IoCtlCleanup", (void *)(uintptr_t)SUPR0IoCtlCleanup }, /* only-windows */ 237 #endif 233 238 { "SUPSemEventClose", (void *)(uintptr_t)SUPSemEventClose }, 234 239 { "SUPSemEventCreate", (void *)(uintptr_t)SUPSemEventCreate }, -
trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h
r71075 r71136 214 214 * @remarks 0x002a0000 is used by 5.1. The next version number must be 0x002b0000. 215 215 */ 216 #define SUPDRV_IOC_VERSION 0x0029000 2216 #define SUPDRV_IOC_VERSION 0x00290003 217 217 218 218 /** SUP_IOCTL_COOKIE. */ -
trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
r70917 r71136 455 455 uint32_t volatile cUsage; 456 456 } SUPDRVUSAGE, *PSUPDRVUSAGE; 457 458 459 /** 460 * I/O control context. 461 */ 462 typedef struct SUPR0IOCTLCTX 463 { 464 /** Magic value (SUPR0IOCTLCTX_MAGIC). */ 465 uint32_t u32Magic; 466 /** Reference counter. */ 467 uint32_t volatile cRefs; 468 #ifdef RT_OS_WINDOWS 469 # ifndef SUPDRV_AGNOSTIC 470 /** The file object, referenced. */ 471 PFILE_OBJECT pFileObject; 472 /** The device object, not referenced. */ 473 PDEVICE_OBJECT pDeviceObject; 474 /** Pointer to fast I/O routine if available. */ 475 FAST_IO_DEVICE_CONTROL *pfnFastIoDeviceControl; 476 # else 477 void *apvPadding[3]; 478 # endif 479 #endif 480 } SUPR0IOCTLCTX; 481 /** Magic value for SUPR0IOCTLCTX (Ahmad Jamal). */ 482 #define SUPR0IOCTLCTX_MAGIC UINT32_C(0x19300702) 457 483 458 484 -
trunk/src/VBox/HostDrivers/Support/SUPLib.cpp
r71075 r71136 277 277 CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION; 278 278 const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x00290000 279 ? 0x0029000 2279 ? 0x00290003 280 280 : SUPDRV_IOC_VERSION & 0xffff0000; 281 281 CookieReq.u.In.u32MinVersion = uMinVersion; -
trunk/src/VBox/HostDrivers/Support/SUPLibLdr.cpp
r69500 r71136 167 167 * Only SUPR0 and VMMR0.r0 168 168 */ 169 if ( pszModule 170 && *pszModule 171 && strcmp(pszModule, "VBoxDrv.sys") 172 && strcmp(pszModule, "VMMR0.r0")) 173 { 169 if ( pszModule 170 && *pszModule 171 && strcmp(pszModule, "VBoxDrv.sys") 172 && strcmp(pszModule, "VMMR0.r0")) 173 { 174 #if defined(RT_OS_WINDOWS) && 0 /* Useful for VMMR0 hacking, not for production use. See also SUPDrv-win.cpp */ 175 if (strcmp(pszModule, "ntoskrnl.exe") == 0) 176 { 177 *pValue = 42; /* Non-zero so ring-0 can find the end of the IAT and exclude it when comparing. */ 178 return VINF_SUCCESS; 179 } 180 #endif 174 181 AssertMsgFailed(("%s is importing from %s! (expected 'SUPR0.dll' or 'VMMR0.r0', case-sensitive)\n", pArgs->pszModule, pszModule)); 175 182 return RTErrInfoSetF(pArgs->pErrInfo, VERR_SYMBOL_NOT_FOUND, -
trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
r70917 r71136 2131 2131 } 2132 2132 2133 /** Image compare exclusion regions. */ 2134 typedef struct SUPDRVNTEXCLREGIONS 2135 { 2136 /** Number of regions. */ 2137 uint32_t cRegions; 2138 /** The regions. */ 2139 struct SUPDRVNTEXCLREGION 2140 { 2141 uint32_t uRva; 2142 uint32_t cb; 2143 } aRegions[16]; 2144 } SUPDRVNTEXCLREGIONS; 2145 2146 /** 2147 * Adds an exclusion region to the collection. 2148 */ 2149 static bool supdrvNtAddExclRegion(SUPDRVNTEXCLREGIONS *pRegions, uint32_t uRvaRegion, uint32_t cbRegion) 2150 { 2151 uint32_t const cRegions = pRegions->cRegions; 2152 AssertReturn(cRegions + 1 <= RT_ELEMENTS(pRegions->aRegions), false); 2153 uint32_t i = 0; 2154 for (; i < cRegions; i++) 2155 if (uRvaRegion < pRegions->aRegions[i].uRva) 2156 break; 2157 if (i != cRegions) 2158 memmove(&pRegions->aRegions[i + 1], &pRegions->aRegions[i], (cRegions - i) * sizeof(pRegions->aRegions[0])); 2159 pRegions->aRegions[i].uRva = uRvaRegion; 2160 pRegions->aRegions[i].cb = cbRegion; 2161 pRegions->cRegions++; 2162 return true; 2163 } 2164 2133 2165 2134 2166 int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq) … … 2184 2216 ) 2185 2217 { 2186 struct MyRegion 2187 { 2188 uint32_t uRva; 2189 uint32_t cb; 2190 } aExcludeRgns[16]; 2191 unsigned cExcludeRgns = 0; 2218 SUPDRVNTEXCLREGIONS ExcludeRegions; 2219 ExcludeRegions.cRegions = 0; 2192 2220 2193 2221 /* ImageBase: */ … … 2195 2223 && ( pNtHdrsNtLd->OptionalHeader.ImageBase == (uintptr_t)pImage->pvImage 2196 2224 || pNtHdrsIprt->OptionalHeader.ImageBase == (uintptr_t)pImage->pvImage) ) 2197 { 2198 aExcludeRgns[cExcludeRgns].uRva = offImageBase; 2199 aExcludeRgns[cExcludeRgns].cb = cbImageBase; 2200 cExcludeRgns++; 2201 } 2225 supdrvNtAddExclRegion(&ExcludeRegions, offImageBase, cbImageBase); 2202 2226 2203 2227 /* Imports: */ … … 2208 2232 IMAGE_IMPORT_DESCRIPTOR const *pImp = (IMAGE_IMPORT_DESCRIPTOR const *)(pbImageBits + offImps); 2209 2233 while ( cImpsLeft-- > 0 2210 && cExcludeRgns < RT_ELEMENTS(aExcludeRgns))2234 && ExcludeRegions.cRegions < RT_ELEMENTS(ExcludeRegions.aRegions)) 2211 2235 { 2212 2236 uint32_t uRvaThunk = pImp->OriginalFirstThunk; 2213 if ( 2214 && 2215 && 2237 if ( uRvaThunk > sizeof(IMAGE_NT_HEADERS) 2238 && uRvaThunk <= pImage->cbImageBits - sizeof(IMAGE_THUNK_DATA) 2239 && uRvaThunk != pImp->FirstThunk) 2216 2240 { 2217 2241 /* Find the size of the thunk table. */ … … 2221 2245 while (cThunks < cMaxThunks && paThunk[cThunks].u1.Function != 0) 2222 2246 cThunks++; 2223 2224 /* Ordered table insert. */ 2225 unsigned i = 0; 2226 for (; i < cExcludeRgns; i++) 2227 if (uRvaThunk < aExcludeRgns[i].uRva) 2228 break; 2229 if (i != cExcludeRgns) 2230 memmove(&aExcludeRgns[i + 1], &aExcludeRgns[i], (cExcludeRgns - i) * sizeof(aExcludeRgns[0])); 2231 aExcludeRgns[i].uRva = uRvaThunk; 2232 aExcludeRgns[i].cb = cThunks * sizeof(IMAGE_THUNK_DATA); 2233 cExcludeRgns++; 2247 supdrvNtAddExclRegion(&ExcludeRegions, uRvaThunk, cThunks * sizeof(IMAGE_THUNK_DATA)); 2234 2248 } 2249 2250 #if 0 /* Useful for VMMR0 hacking, not for production use. See also SUPDrvLdr.cpp. */ 2251 /* Exclude the other thunk table if ntoskrnl.exe. */ 2252 uint32_t uRvaName = pImp->Name; 2253 if ( uRvaName > sizeof(IMAGE_NT_HEADERS) 2254 && uRvaName < pImage->cbImageBits - sizeof("ntoskrnl.exe") 2255 && memcmp(&pbImageBits[uRvaName], RT_STR_TUPLE("ntoskrnl.exe")) == 0) 2256 { 2257 uRvaThunk = pImp->FirstThunk; 2258 if ( uRvaThunk > sizeof(IMAGE_NT_HEADERS) 2259 && uRvaThunk <= pImage->cbImageBits - sizeof(IMAGE_THUNK_DATA)) 2260 { 2261 /* Find the size of the thunk table. */ 2262 IMAGE_THUNK_DATA const *paThunk = (IMAGE_THUNK_DATA const *)(pbImageBits + uRvaThunk); 2263 uint32_t cMaxThunks = (pImage->cbImageBits - uRvaThunk) / sizeof(IMAGE_THUNK_DATA); 2264 uint32_t cThunks = 0; 2265 while (cThunks < cMaxThunks && paThunk[cThunks].u1.Function != 0) 2266 cThunks++; 2267 supdrvNtAddExclRegion(&ExcludeRegions, uRvaThunk, cThunks * sizeof(IMAGE_THUNK_DATA)); 2268 } 2269 } 2270 #endif 2235 2271 2236 2272 /* advance */ … … 2243 2279 int iDiff = 0; 2244 2280 uint32_t uRvaNext = 0; 2245 for (unsigned i = 0; !iDiff && i < cExcludeRgns; i++)2246 { 2247 if (uRvaNext < aExcludeRgns[i].uRva)2248 iDiff = supdrvNtCompare(pImage, pbImageBits, uRvaNext, aExcludeRgns[i].uRva - uRvaNext, pReq);2249 uRvaNext = aExcludeRgns[i].uRva + aExcludeRgns[i].cb;2281 for (unsigned i = 0; !iDiff && i < ExcludeRegions.cRegions; i++) 2282 { 2283 if (uRvaNext < ExcludeRegions.aRegions[i].uRva) 2284 iDiff = supdrvNtCompare(pImage, pbImageBits, uRvaNext, ExcludeRegions.aRegions[i].uRva - uRvaNext, pReq); 2285 uRvaNext = ExcludeRegions.aRegions[i].uRva + ExcludeRegions.aRegions[i].cb; 2250 2286 } 2251 2287 if (!iDiff && uRvaNext < pImage->cbImageBits) … … 2558 2594 { 2559 2595 return 0; 2596 } 2597 2598 2599 SUPR0DECL(int) SUPR0IoCtlSetupForHandle(PSUPDRVSESSION pSession, intptr_t hHandle, uint32_t fFlags, PSUPR0IOCTLCTX *ppCtx) 2600 { 2601 /* 2602 * Validate input. 2603 */ 2604 AssertPtrReturn(ppCtx, VERR_INVALID_POINTER); 2605 *ppCtx = NULL; 2606 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER); 2607 AssertReturn(!fFlags, VERR_INVALID_FLAGS); 2608 2609 /* 2610 * Turn the partition handle into a file object and related device object 2611 * so that we can issue direct I/O control calls to the pair later. 2612 */ 2613 PFILE_OBJECT pFileObject = NULL; 2614 OBJECT_HANDLE_INFORMATION HandleInfo = { 0, 0 }; 2615 NTSTATUS rcNt = ObReferenceObjectByHandle((HANDLE)hHandle, /*FILE_WRITE_DATA*/0, *IoFileObjectType, 2616 UserMode, (void **)&pFileObject, &HandleInfo); 2617 if (!NT_SUCCESS(rcNt)) 2618 return RTErrConvertFromNtStatus(rcNt); 2619 AssertPtrReturn(pFileObject, VERR_INTERNAL_ERROR_3); 2620 2621 PDEVICE_OBJECT pDevObject = IoGetRelatedDeviceObject(pFileObject); 2622 AssertMsgReturnStmt(RT_VALID_PTR(pDevObject), ("pDevObject=%p\n", pDevObject), 2623 ObDereferenceObject(pFileObject), VERR_INTERNAL_ERROR_2); 2624 2625 /* 2626 * Allocate a context structure and fill it in. 2627 */ 2628 PSUPR0IOCTLCTX pCtx = (PSUPR0IOCTLCTX)RTMemAllocZ(sizeof(*pCtx)); 2629 if (pCtx) 2630 { 2631 pCtx->u32Magic = SUPR0IOCTLCTX_MAGIC; 2632 pCtx->cRefs = 1; 2633 pCtx->pFileObject = pFileObject; 2634 pCtx->pDeviceObject = pDevObject; 2635 2636 PDRIVER_OBJECT pDrvObject = pDevObject->DriverObject; 2637 if ( RT_VALID_PTR(pDrvObject->FastIoDispatch) 2638 && RT_VALID_PTR(pDrvObject->FastIoDispatch->FastIoDeviceControl)) 2639 pCtx->pfnFastIoDeviceControl = pDrvObject->FastIoDispatch->FastIoDeviceControl; 2640 else 2641 pCtx->pfnFastIoDeviceControl = NULL; 2642 *ppCtx = pCtx; 2643 return VINF_SUCCESS; 2644 } 2645 2646 ObDereferenceObject(pFileObject); 2647 return VERR_NO_MEMORY; 2648 } 2649 2650 2651 /** 2652 * I/O control destructor for NT. 2653 * 2654 * @param pCtx The context to destroy. 2655 */ 2656 static void supdrvNtIoCtlContextDestroy(PSUPR0IOCTLCTX pCtx) 2657 { 2658 PFILE_OBJECT pFileObject = pCtx->pFileObject; 2659 pCtx->pfnFastIoDeviceControl = NULL; 2660 pCtx->pFileObject = NULL; 2661 pCtx->pDeviceObject = NULL; 2662 ASMAtomicWriteU32(&pCtx->u32Magic, ~SUPR0IOCTLCTX_MAGIC); 2663 2664 if (RT_VALID_PTR(pFileObject)) 2665 ObDereferenceObject(pFileObject); 2666 RTMemFree(pCtx); 2667 } 2668 2669 2670 SUPR0DECL(int) SUPR0IoCtlCleanup(PSUPR0IOCTLCTX pCtx) 2671 { 2672 if (pCtx != NULL) 2673 { 2674 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 2675 AssertReturn(pCtx->u32Magic == SUPR0IOCTLCTX_MAGIC, VERR_INVALID_PARAMETER); 2676 2677 uint32_t cRefs = ASMAtomicDecU32(&pCtx->cRefs); 2678 Assert(cRefs < _4K); 2679 if (cRefs == 0) 2680 supdrvNtIoCtlContextDestroy(pCtx); 2681 } 2682 return VINF_SUCCESS; 2683 } 2684 2685 2686 SUPR0DECL(int) SUPR0IoCtlPerform(PSUPR0IOCTLCTX pCtx, uintptr_t uFunction, 2687 void *pvInput, RTR3PTR pvInputUser, size_t cbInput, 2688 void *pvOutput, RTR3PTR pvOutputUser, size_t cbOutput, 2689 int32_t *piNativeRc) 2690 { 2691 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 2692 AssertReturn(pCtx->u32Magic == SUPR0IOCTLCTX_MAGIC, VERR_INVALID_PARAMETER); 2693 2694 /* Reference the context. */ 2695 uint32_t cRefs = ASMAtomicIncU32(&pCtx->cRefs); 2696 Assert(cRefs > 1 && cRefs < _4K); 2697 2698 /* 2699 * Try fast I/O control path first. 2700 */ 2701 IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER; 2702 if (pCtx->pfnFastIoDeviceControl) 2703 { 2704 /* Must pass user addresses here as that's what's being expected. */ 2705 BOOLEAN fHandled = pCtx->pfnFastIoDeviceControl(pCtx->pFileObject, 2706 TRUE /*Wait*/, 2707 (void *)pvInputUser, (ULONG)cbInput, 2708 (void *)pvOutputUser, (ULONG)cbOutput, 2709 uFunction, 2710 &Ios, 2711 pCtx->pDeviceObject); 2712 if (fHandled) 2713 { 2714 /* Relase the context. */ 2715 cRefs = ASMAtomicDecU32(&pCtx->cRefs); 2716 Assert(cRefs < _4K); 2717 if (cRefs == 0) 2718 supdrvNtIoCtlContextDestroy(pCtx); 2719 2720 /* Set/convert status and return. */ 2721 if (piNativeRc) 2722 { 2723 *piNativeRc = Ios.Status; 2724 return VINF_SUCCESS; 2725 } 2726 if (NT_SUCCESS(Ios.Status)) 2727 return VINF_SUCCESS; 2728 return RTErrConvertFromNtStatus(Ios.Status); 2729 } 2730 2731 /* 2732 * Fall back on IRP if not handled. 2733 * 2734 * Note! Perhaps we should rather fail, because VID.SYS will crash getting 2735 * the partition ID with the code below. It tries to zero the output 2736 * buffer as if it were as system buffer... 2737 */ 2738 RTNT_IO_STATUS_BLOCK_REINIT(&Ios); 2739 } 2740 2741 /* 2742 * For directly accessed buffers we must supply user mode addresses or 2743 * we'll fail ProbeForWrite validation. 2744 */ 2745 switch (uFunction & 3) 2746 { 2747 case METHOD_BUFFERED: 2748 /* For buffered accesses, we can supply kernel buffers. */ 2749 break; 2750 2751 case METHOD_IN_DIRECT: 2752 pvInput = (void *)pvInputUser; 2753 break; 2754 2755 case METHOD_NEITHER: 2756 pvInput = (void *)pvInputUser; 2757 RT_FALL_THRU(); 2758 2759 case METHOD_OUT_DIRECT: 2760 pvOutput = (void *)pvOutputUser; 2761 break; 2762 } 2763 2764 /* 2765 * Build the request. 2766 */ 2767 int rc; 2768 KEVENT Event; 2769 KeInitializeEvent(&Event, NotificationEvent, FALSE); 2770 2771 PIRP pIrp = IoBuildDeviceIoControlRequest(uFunction, pCtx->pDeviceObject, 2772 pvInput, (ULONG)cbInput, pvOutput, (ULONG)cbOutput, 2773 FALSE /* InternalDeviceControl */, &Event, &Ios); 2774 if (pIrp) 2775 { 2776 IoGetNextIrpStackLocation(pIrp)->FileObject = pCtx->pFileObject; 2777 2778 /* 2779 * Make the call. 2780 */ 2781 NTSTATUS rcNt = IoCallDriver(pCtx->pDeviceObject, pIrp); 2782 if (rcNt == STATUS_PENDING) 2783 { 2784 rcNt = KeWaitForSingleObject(&Event, /* Object */ 2785 Executive, /* WaitReason */ 2786 KernelMode, /* WaitMode */ 2787 FALSE, /* Alertable */ 2788 NULL); /* TimeOut */ 2789 AssertMsg(rcNt == STATUS_SUCCESS, ("rcNt=%#x\n", rcNt)); 2790 rcNt = Ios.Status; 2791 } 2792 else if (NT_SUCCESS(rcNt) && Ios.Status != STATUS_SUCCESS) 2793 rcNt = Ios.Status; 2794 2795 /* Set/convert return code. */ 2796 if (piNativeRc) 2797 { 2798 *piNativeRc = rcNt; 2799 rc = VINF_SUCCESS; 2800 } 2801 else if (NT_SUCCESS(rcNt)) 2802 rc = VINF_SUCCESS; 2803 else 2804 rc = RTErrConvertFromNtStatus(rcNt); 2805 } 2806 else 2807 { 2808 if (piNativeRc) 2809 *piNativeRc = STATUS_NO_MEMORY; 2810 rc = VERR_NO_MEMORY; 2811 } 2812 2813 /* Relase the context. */ 2814 cRefs = ASMAtomicDecU32(&pCtx->cRefs); 2815 Assert(cRefs < _4K); 2816 if (cRefs == 0) 2817 supdrvNtIoCtlContextDestroy(pCtx); 2818 2819 return rc; 2560 2820 } 2561 2821
Note:
See TracChangeset
for help on using the changeset viewer.