- Timestamp:
- Oct 15, 2015 6:18:17 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp
r57358 r58268 77 77 PMDL apMdls[1]; 78 78 } RTR0MEMOBJNT, *PRTR0MEMOBJNT; 79 80 81 /********************************************************************************************************************************* 82 * Global Variables * 83 *********************************************************************************************************************************/ 84 /** Pointer to the MmProtectMdlSystemAddress kernel function if it's available. 85 * This API was introduced in XP. */ 86 static decltype(MmProtectMdlSystemAddress) *g_pfnMmProtectMdlSystemAddress = NULL; 87 /** Set if we've resolved the dynamic APIs. */ 88 static bool volatile g_fResolvedDynamicApis = false; 89 static ULONG g_uMajorVersion = 5; 90 static ULONG g_uMinorVersion = 1; 91 92 93 static void rtR0MemObjNtResolveDynamicApis(void) 94 { 95 ULONG uBuildNumber = 0; 96 PsGetVersion(&g_uMajorVersion, &g_uMinorVersion, &uBuildNumber, NULL); 97 98 #ifndef IPRT_TARGET_NT4 /* MmGetSystemRoutineAddress was introduced in w2k. */ 99 100 UNICODE_STRING RoutineName; 101 RtlInitUnicodeString(&RoutineName, L"MmProtectMdlSystemAddress"); 102 g_pfnMmProtectMdlSystemAddress = (decltype(MmProtectMdlSystemAddress) *)MmGetSystemRoutineAddress(&RoutineName); 103 104 #endif 105 ASMCompilerBarrier(); 106 g_fResolvedDynamicApis = true; 107 } 79 108 80 109 … … 820 849 DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt) 821 850 { 822 NOREF(pMem); 823 NOREF(offSub); 824 NOREF(cbSub); 825 NOREF(fProt); 851 PRTR0MEMOBJNT pMemNt = (PRTR0MEMOBJNT)pMem; 852 if (!g_fResolvedDynamicApis) 853 rtR0MemObjNtResolveDynamicApis(); 854 855 /* 856 * Seems there are some issues with this MmProtectMdlSystemAddress API, so 857 * this code isn't currently enabled until we've tested it with the verifier. 858 */ 859 #if 0 860 /* 861 * The API we've got requires a kernel mapping. 862 */ 863 if ( pMemNt->cMdls 864 && g_pfnMmProtectMdlSystemAddress 865 && (g_uMajorVersion > 6 || (g_uMajorVersion == 6 && g_uMinorVersion >= 1)) /* Windows 7 and later. */ 866 && pMemNt->Core.pv != NULL 867 && ( pMemNt->Core.enmType == RTR0MEMOBJTYPE_PAGE 868 || pMemNt->Core.enmType == RTR0MEMOBJTYPE_LOW 869 || pMemNt->Core.enmType == RTR0MEMOBJTYPE_CONT 870 || ( pMemNt->Core.enmType == RTR0MEMOBJTYPE_LOCK 871 && pMemNt->Core.u.Lock.R0Process == NIL_RTPROCESS) 872 || ( pMemNt->Core.enmType == RTR0MEMOBJTYPE_MAPPING 873 && pMemNt->Core.u.Mapping.R0Process == NIL_RTPROCESS) ) ) 874 { 875 /* Convert the protection. */ 876 LOCK_OPERATION enmLockOp; 877 ULONG fAccess; 878 switch (fProt) 879 { 880 case RTMEM_PROT_NONE: 881 fAccess = PAGE_NOACCESS; 882 enmLockOp = IoReadAccess; 883 break; 884 case RTMEM_PROT_READ: 885 fAccess = PAGE_READONLY; 886 enmLockOp = IoReadAccess; 887 break; 888 case RTMEM_PROT_WRITE: 889 case RTMEM_PROT_WRITE | RTMEM_PROT_READ: 890 fAccess = PAGE_READWRITE; 891 enmLockOp = IoModifyAccess; 892 break; 893 case RTMEM_PROT_EXEC: 894 fAccess = PAGE_EXECUTE; 895 enmLockOp = IoReadAccess; 896 break; 897 case RTMEM_PROT_EXEC | RTMEM_PROT_READ: 898 fAccess = PAGE_EXECUTE_READ; 899 enmLockOp = IoReadAccess; 900 break; 901 case RTMEM_PROT_EXEC | RTMEM_PROT_WRITE: 902 case RTMEM_PROT_EXEC | RTMEM_PROT_WRITE | RTMEM_PROT_READ: 903 fAccess = PAGE_EXECUTE_READWRITE; 904 enmLockOp = IoModifyAccess; 905 break; 906 default: 907 AssertFailedReturn(VERR_INVALID_FLAGS); 908 } 909 910 NTSTATUS rcNt = STATUS_SUCCESS; 911 # if 0 /** @todo test this against the verifier. */ 912 if (offSub == 0 && pMemNt->Core.cb == cbSub) 913 { 914 uint32_t iMdl = pMemNt->cMdls; 915 while (iMdl-- > 0) 916 { 917 rcNt = g_pfnMmProtectMdlSystemAddress(pMemNt->apMdls[i], fAccess); 918 if (!NT_SUCCESS(rcNt)) 919 break; 920 } 921 } 922 else 923 # endif 924 { 925 /* 926 * We ASSUME the following here: 927 * - MmProtectMdlSystemAddress can deal with nonpaged pool memory 928 * - MmProtectMdlSystemAddress doesn't actually store anything in the MDL we pass it. 929 * - We are not required to call MmProtectMdlSystemAddress with PAGE_READWRITE for the 930 * exact same ranges prior to freeing them. 931 * 932 * So, we lock the pages temporarily, call the API and unlock them. 933 */ 934 uint8_t *pbCur = (uint8_t *)pMemNt->Core.pv + offSub; 935 while (cbSub > 0 && NT_SUCCESS(rcNt)) 936 { 937 size_t cbCur = cbSub; 938 if (cbCur > MAX_LOCK_MEM_SIZE) 939 cbCur = MAX_LOCK_MEM_SIZE; 940 PMDL pMdl = IoAllocateMdl(pbCur, (ULONG)cbCur, FALSE, FALSE, NULL); 941 if (pMdl) 942 { 943 __try 944 { 945 MmProbeAndLockPages(pMdl, KernelMode, enmLockOp); 946 } 947 __except(EXCEPTION_EXECUTE_HANDLER) 948 { 949 rcNt = GetExceptionCode(); 950 } 951 if (NT_SUCCESS(rcNt)) 952 { 953 rcNt = g_pfnMmProtectMdlSystemAddress(pMdl, fAccess); 954 MmUnlockPages(pMdl); 955 } 956 IoFreeMdl(pMdl); 957 } 958 else 959 rcNt = STATUS_NO_MEMORY; 960 pbCur += cbCur; 961 cbSub -= cbCur; 962 } 963 } 964 965 if (NT_SUCCESS(rcNt)) 966 return VINF_SUCCESS; 967 return RTErrConvertFromNtStatus(rcNt); 968 } 969 #endif 970 826 971 return VERR_NOT_SUPPORTED; 827 972 }
Note:
See TracChangeset
for help on using the changeset viewer.