1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * PURPOSE: GDI Driver Memory Management Functions 5 * FILE: win32ss/gdi/eng/mem.c 6 * PROGRAMER: Jason Filby 7 */ 8 9 #include <win32k.h> 10 11 #define NDEBUG 12 #include <debug.h> 13 14 /* 15 * @implemented 16 */ 17 _Must_inspect_result_ 18 _When_(fl & FL_ZERO_MEMORY, _Ret_opt_bytecount_(cjMemSize)) 19 _When_(!(fl & FL_ZERO_MEMORY), _Ret_opt_bytecap_(cjMemSize)) 20 __drv_allocatesMem(Mem) 21 ENGAPI 22 PVOID 23 APIENTRY 24 EngAllocMem( 25 _In_ ULONG fl, 26 _In_ ULONG cjMemSize, 27 _In_ ULONG ulTag) 28 { 29 PVOID pvBaseAddress; 30 31 pvBaseAddress = ExAllocatePoolWithTag((fl & FL_NONPAGED_MEMORY) ? 32 NonPagedPool : PagedPool, 33 cjMemSize, 34 ulTag); 35 36 if (pvBaseAddress == NULL) 37 return NULL; 38 39 if (fl & FL_ZERO_MEMORY) 40 RtlZeroMemory(pvBaseAddress, cjMemSize); 41 42 return pvBaseAddress; 43 } 44 45 /* 46 * @implemented 47 */ 48 VOID 49 APIENTRY 50 EngFreeMem(PVOID pvBaseAddress) 51 { 52 /* Windows allows to pass NULL */ 53 if (pvBaseAddress) 54 { 55 /* Use 0 as tag, which equals a call to ExFreePool */ 56 ExFreePoolWithTag(pvBaseAddress, 0); 57 } 58 } 59 60 /* 61 * @implemented 62 */ 63 _Must_inspect_result_ 64 _Ret_opt_bytecount_(cjMemSize) 65 __drv_allocatesMem(UserMem) 66 ENGAPI 67 PVOID 68 APIENTRY 69 EngAllocUserMem( 70 _In_ SIZE_T cjMemSize, 71 _In_ ULONG ulTag) 72 { 73 PVOID pvBaseAddress = NULL; 74 NTSTATUS Status; 75 76 Status = ZwAllocateVirtualMemory(NtCurrentProcess(), 77 &pvBaseAddress, 78 0, 79 &cjMemSize, 80 MEM_COMMIT | MEM_RESERVE, 81 PAGE_READWRITE); 82 83 if (!NT_SUCCESS(Status)) 84 { 85 return NULL; 86 } 87 88 /* TODO: Add allocation info to AVL tree (stored inside W32PROCESS structure) */ 89 //hSecure = EngSecureMem(pvBaseAddress, cj); 90 91 return pvBaseAddress; 92 } 93 94 /* 95 * @implemented 96 */ 97 VOID 98 APIENTRY 99 EngFreeUserMem(PVOID pvBaseAddress) 100 { 101 SIZE_T cjSize = 0; 102 103 ZwFreeVirtualMemory(NtCurrentProcess(), 104 &pvBaseAddress, 105 &cjSize, 106 MEM_RELEASE); 107 108 /* TODO: Remove allocation info from AVL tree */ 109 } 110 111 PVOID 112 APIENTRY 113 HackSecureVirtualMemory( 114 IN PVOID Address, 115 IN SIZE_T Size, 116 IN ULONG ProbeMode, 117 OUT PVOID *SafeAddress) 118 { 119 NTSTATUS Status = STATUS_SUCCESS; 120 PMDL pmdl; 121 LOCK_OPERATION Operation; 122 123 if (ProbeMode == PAGE_READONLY) Operation = IoReadAccess; 124 else if (ProbeMode == PAGE_READWRITE) Operation = IoModifyAccess; 125 else return NULL; 126 127 pmdl = IoAllocateMdl(Address, (ULONG)Size, FALSE, TRUE, NULL); 128 if (pmdl == NULL) 129 { 130 return NULL; 131 } 132 133 _SEH2_TRY 134 { 135 MmProbeAndLockPages(pmdl, UserMode, Operation); 136 } 137 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 138 { 139 Status = _SEH2_GetExceptionCode(); 140 } 141 _SEH2_END 142 143 if (!NT_SUCCESS(Status)) 144 { 145 IoFreeMdl(pmdl); 146 return NULL; 147 } 148 149 *SafeAddress = MmGetSystemAddressForMdlSafe(pmdl, NormalPagePriority); 150 151 if(!*SafeAddress) 152 { 153 MmUnlockPages(pmdl); 154 IoFreeMdl(pmdl); 155 return NULL; 156 } 157 158 return pmdl; 159 } 160 161 VOID 162 APIENTRY 163 HackUnsecureVirtualMemory( 164 IN PVOID SecureHandle) 165 { 166 PMDL pmdl = (PMDL)SecureHandle; 167 168 MmUnlockPages(pmdl); 169 IoFreeMdl(pmdl); 170 } 171 172 /* 173 * @implemented 174 */ 175 HANDLE 176 APIENTRY 177 EngSecureMem(PVOID Address, ULONG Length) 178 { 179 {// HACK!!! 180 _SEH2_TRY 181 { 182 ProbeForWrite(Address, Length, 1); 183 } 184 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 185 { 186 _SEH2_YIELD(return NULL); 187 } 188 _SEH2_END; 189 return (HANDLE)-1; 190 } 191 return MmSecureVirtualMemory(Address, Length, PAGE_READWRITE); 192 } 193 194 HANDLE 195 APIENTRY 196 EngSecureMemForRead(PVOID Address, ULONG Length) 197 { 198 {// HACK!!! 199 ULONG cPages; 200 volatile BYTE *pjProbe; 201 202 _SEH2_TRY 203 { 204 ProbeForRead(Address, Length, 1); 205 cPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Address, Length); 206 pjProbe = ALIGN_DOWN_POINTER_BY(Address, PAGE_SIZE); 207 while(cPages--) 208 { 209 /* Do a read probe */ 210 (void)*pjProbe; 211 pjProbe += PAGE_SIZE; 212 } 213 } 214 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 215 { 216 _SEH2_YIELD(return NULL); 217 } 218 _SEH2_END; 219 return (HANDLE)-1; 220 } 221 return MmSecureVirtualMemory(Address, Length, PAGE_READONLY); 222 } 223 224 /* 225 * @implemented 226 */ 227 VOID APIENTRY 228 EngUnsecureMem(HANDLE Mem) 229 { 230 if (Mem == (HANDLE)-1) return; // HACK!!! 231 MmUnsecureVirtualMemory((PVOID) Mem); 232 } 233 234 /* EOF */ 235