- Timestamp:
- Feb 19, 2001, 6:49:05 AM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/win32k/k32/k32AllocMemEx.cpp
r4787 r5179 1 /* $Id: k32AllocMemEx.cpp,v 1. 4 2000-12-11 06:53:52bird Exp $1 /* $Id: k32AllocMemEx.cpp,v 1.5 2001-02-19 05:49:05 bird Exp $ 2 2 * 3 3 * k32AllocMemEx - Equivalent to DosAllocMem, but this one … … 17 17 #define INCL_DOSERRORS 18 18 #define INCL_OS2KRNL_VM 19 #define INCL_OS2KRNL_TK 19 20 20 21 #define NO_WIN32K_LIB_FUNCTIONS 21 22 22 #ifndef OBJ_SELMAPALL23 #define OBJ_SELMAPALL 0x00000800UL24 #endif25 23 26 24 … … 40 38 41 39 /* nasty! These should be imported from the kernel later! */ 42 40 /* 41 * These are unchanged from Warp3 to Warp 4.51. 42 */ 43 43 ULONG vmApiF0[] = 44 44 { 45 0, 46 VMA_READ, 47 VMA_WRITE | VMA_READ, 48 VMA_WRITE | VMA_READ, 49 VMA_EXECUTE, 50 VMA_EXECUTE | VMA_READ, 51 VMA_WRITE | VMA_EXECUTE | VMA_READ, 52 VMA_WRITE | VMA_EXECUTE | VMA_READ, 53 VMA_GUARD, 54 VMA_READ | VMA_GUARD, 55 VMA_WRITE | VMA_READ | VMA_GUARD, 56 VMA_WRITE | VMA_READ | VMA_GUARD, 57 VMA_EXECUTE | VMA_GUARD, 58 VMA_EXECUTE | VMA_READ | VMA_GUARD, 59 VMA_WRITE | VMA_EXECUTE | VMA_READ | VMA_GUARD, 60 VMA_WRITE | VMA_EXECUTE | VMA_READ | VMA_GUARD 45 0, /* 0 */ 46 VMA_READ, /* PAG_READ */ 47 VMA_WRITE | VMA_READ, /* PAG_WRITE */ 48 VMA_WRITE | VMA_READ, /* PAG_READ | PAG_WRITE */ 49 VMA_EXECUTE, /* PAG_EXECUTE */ 50 VMA_EXECUTE | VMA_READ, /* PAG_READ | PAG_EXECUTE */ 51 VMA_WRITE | VMA_EXECUTE | VMA_READ, /* PAG_WRITE | PAG_EXECUTE */ 52 VMA_WRITE | VMA_EXECUTE | VMA_READ, /* PAG_READ | PAG_WRITE | PAG_EXECUTE */ 53 VMA_GUARD, /* PAG_GUARD */ 54 VMA_READ | VMA_GUARD, /* PAG_READ | PAG_GUARD */ 55 VMA_WRITE | VMA_READ | VMA_GUARD, /* PAG_WRITE | PAG_GUARD */ 56 VMA_WRITE | VMA_READ | VMA_GUARD, /* PAG_READ | PAG_WRITE | PAG_GUARD */ 57 VMA_EXECUTE | VMA_GUARD, /* PAG_EXECUTE | PAG_GUARD */ 58 VMA_EXECUTE | VMA_READ | VMA_GUARD, /* PAG_READ | PAG_EXECUTE | PAG_GUARD */ 59 VMA_WRITE | VMA_EXECUTE | VMA_READ | VMA_GUARD, /* PAG_WRITE | PAG_EXECUTE | PAG_GUARD */ 60 VMA_WRITE | VMA_EXECUTE | VMA_READ | VMA_GUARD /* PAG_READ | PAG_WRITE | PAG_EXECUTE | PAG_GUARD */ 61 61 }; 62 63 62 64 63 ULONG vmApiF1[] = 65 64 { 66 0, 67 0, 68 VMA_DECOMMIT, 69 VMA_DECOMMIT, 70 VMA_ TILE,71 VMA_ TILE,72 VMA_DECOMMIT | VMA_ TILE,73 VMA_DECOMMIT | VMA_ TILE,74 VMA_PROTECTED, 75 VMA_PROTECTED, 76 VMA_PROTECTED | VMA_DECOMMIT, 77 VMA_PROTECTED | VMA_DECOMMIT, 78 VMA_PROTECTED | VMA_ TILE,79 VMA_PROTECTED | VMA_ TILE,80 VMA_PROTECTED | VMA_DECOMMIT | VMA_ TILE,81 VMA_PROTECTED | VMA_DECOMMIT | VMA_ TILE65 0, /* 0 */ 66 0, /* PAG_COMMIT */ 67 VMA_DECOMMIT, /* PAG_DECOMMIT */ 68 VMA_DECOMMIT, /* PAG_COMMIT | PAG_DECOMMIT */ 69 VMA_SELALLOC, /* OBJ_TILE */ 70 VMA_SELALLOC, /* PAG_COMMIT | OBJ_TILE */ 71 VMA_DECOMMIT | VMA_SELALLOC, /* PAG_DECOMMIT | OBJ_TILE */ 72 VMA_DECOMMIT | VMA_SELALLOC, /* PAG_COMMIT | PAG_DECOMMIT | OBJ_TILE */ 73 VMA_PROTECTED, /* OBJ_PROTECTED */ 74 VMA_PROTECTED, /* PAG_COMMIT | OBJ_PROTECTED */ 75 VMA_PROTECTED | VMA_DECOMMIT, /* PAG_DECOMMIT | OBJ_PROTECTED */ 76 VMA_PROTECTED | VMA_DECOMMIT, /* PAG_COMMIT | PAG_DECOMMIT | OBJ_PROTECTED */ 77 VMA_PROTECTED | VMA_SELALLOC, /* OBJ_TILE | OBJ_PROTECTED */ 78 VMA_PROTECTED | VMA_SELALLOC, /* PAG_COMMIT | OBJ_TILE | OBJ_PROTECTED */ 79 VMA_PROTECTED | VMA_DECOMMIT | VMA_SELALLOC, /* PAG_DECOMMIT | OBJ_TILE | OBJ_PROTECTED */ 80 VMA_PROTECTED | VMA_DECOMMIT | VMA_SELALLOC /* PAG_COMMIT | PAG_DECOMMIT | OBJ_TILE | OBJ_PROTECTED */ 82 81 }; 83 82 84 83 85 84 /** 86 * Extended edition of DosAllocMem. Allows you to suggest an address where you 87 * want the memory allocated. 88 * @returns OS2 returncode. 89 * @param ppv Pointer to a pointer. This points to a pointer which points to the 90 * suggested address of the memory block. 91 * @param cb Size of the memory block. 92 * @param flag Flags just as for DosAllocMem. 93 * @param ulCS CS where the memoryobject were requested. 94 * @param ulEIP EIP where the memoryobject were requested. 85 * Extended edition of DosAllocMem: 86 * Allows you to suggest an address where you want the memory allocated. 87 * Specify 64KB alignment. 88 * @returns OS2 returncode. 89 * ERROR_INVALID_PARAMETER Some input parameter is bad. 90 * ERROR_INVALID_ADDRESS *pvv is wrong. 91 * @param ppv Pointer to a pointer. 92 * If OBJ_LOCATION is specified this *ppv holds a suggested address of the memory block. 93 * @param cb Size of the memory block. 94 * @param flFlags Flags just as for DosAllocMem and two more: 95 * OBJ_ALIGN64K Align on 64 boundrary. Default in compatibility region. 96 * OBJ_ALIGNPAGE Page align the memory. (only high region) Default in 32-bit region. 97 * OBJ_LOCATION *ppv specifies a suggested address of the memory block. 98 * @param ulCS CS where the memoryobject was requested. 99 * @param ulEIP EIP where the memoryobject was requested. 95 100 * @sketch 96 * @status stub 97 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no) 98 * @remark 101 * @status partially implemented. 102 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no) 103 * @remark Seems like I have to solve that "Grow private arena" problem which 104 * applies when we allocate at a specific address. 105 * I'll look into it ASAP and add a fix for this in the loader too. 99 106 */ 100 APIRET k32AllocMemEx(PPVOID ppv, ULONG cb, ULONG fl ag, ULONG ulCS, ULONG ulEIP)107 APIRET k32AllocMemEx(PPVOID ppv, ULONG cb, ULONG flFlags, ULONG ulCS, ULONG ulEIP) 101 108 { 102 #if 0103 109 APIRET rc; 104 ULONG flFlags2; 110 ULONG flVMFlags; 111 ULONG flSelFlags; 105 112 VMAC vmac = {0}; 106 113 ULONG cbCommit; 107 114 HMTE hMTE; 108 115 109 if ((flag & ~(PAG_READ | PAG_WRITE | PAG_EXECUTE | PAG_GUARD | PAG_COMMIT 110 | OBJ_TILE | OBJ_SELMAPALL)) 111 || (flag & (PAG_READ | PAG_WRITE | PAG_EXECUTE)) == 0UL 116 117 kprintf(("k32AllocMemEx(ppv=0x%08x, cb=0x%x, flFlags=0x%08x, ulCS=0x%04x, ulEIP=0x%08x)\n", 118 ppv, cb, flFlags, ulCS, ulEIP)); 119 120 /** @sketch 121 * General parameter validations: 122 * Only allowable flFlagss - DosAllocMem + our own. 123 * At least one access flag must be set. 124 * OBJ_TILE don't work OBJ_ANY or OBJ_ALIGNPAGE. 125 * Must be larger than 0 bytes. 126 * Caller CS and EIP must not be 0. 127 * Align size and check if it's resonable. 128 * If address is specified Then 129 * Check that the memory block is within possible private address space. 130 */ 131 if ( (flFlags & ~(PAG_READ | PAG_WRITE | PAG_EXECUTE | PAG_GUARD | PAG_COMMIT 132 | OBJ_ANY | OBJ_TILE | OBJ_SELMAPALL | OBJ_ALIGNMASK | OBJ_LOCATION)) 133 || (flFlags & (PAG_READ | PAG_WRITE | PAG_EXECUTE)) == 0 134 || ((flFlags & OBJ_TILE) && ((flFlags & OBJ_ANY) || (flFlags & OBJ_ALIGNMASK) == OBJ_ALIGNPAGE)) 112 135 || cb == 0 113 || ulCS == 0 114 || ulEIP == 0 136 || ulCS == 0 || ulEIP == 0 115 137 ) 138 { 139 kprintf(("k32AllocMemEx: Bad param (1)\n")); 116 140 return ERROR_INVALID_PARAMETER; 117 if (cb > 0xC0000000UL) 141 } 142 143 cb = PAGEALIGNUP(cb); 144 if (cb >= VirtualAddressLimit) 145 { 146 kprintf(("k32AllocMemEx: Bad size cb=%d\n", cb)); 118 147 return ERROR_NOT_ENOUGH_MEMORY; 119 120 vmac.ac_va = (ULONG)*ppv; 121 cb = (cb + 0xFFFUL) & ~0xFFFUL; 122 if (flag & PAG_COMMIT) 123 cbCommit = cb; 124 flag = vmApiF0[flag & (PAG_READ | PAG_WRITE | PAG_EXECUTE | PAG_GUARD)] 125 | vmApiF1[(flag & (PAG_COMMIT | PAG_DECOMMIT | OBJ_TILE | OBJ_PROTECTED)) >> 2] 126 | VMA_USER | VMA_RESIDENT | VMA_LOWMEM2 | VMA_TILE | 0x12000000; 127 flFlags2 = (flag & VMA_WRITE ? VMAF2_WRITE : 0) | 0x460; 128 148 } 149 150 if (flFlags & OBJ_LOCATION) 151 { 152 rc = TKFuULongNF(SSToDS(&vmac.ac_va), ppv); 153 if (rc) 154 { 155 kprintf(("k32AllocMemEx: Failed to fetch *ppv. rc=%d\n", rc)); 156 return rc; 157 } 158 kprintf(("k32AllocMemEx: Location *ppv =0x%08x\n", vmac.ac_va)); 159 if ( vmac.ac_va < 0x10000 160 || vmac.ac_va + cb < vmac.ac_va 161 || vmac.ac_va + cb > ((vmac.ac_va >= 0x20000000 && pahvmhShr) ? pahvmhShr : pahvmShr)->ah_laddrMax 162 ) 163 { 164 kprintf(("k32AllocMemEx: *ppv has an invalid address. *ppv=0x%08x\n", vmac.ac_va)); 165 return ERROR_INVALID_ADDRESS; 166 } 167 } 168 169 170 /** @sketch 171 * Get the hMTE of the executable object we're called from - may fail. 172 * Determin size of precommitted memory. 173 * Determin VM Flags: 174 * Default 175 * Handle OBJ_ANY (only applies if there are high arenas). 176 * Access flags are determined using vmApiF0. 177 * Commit, decommit, tile and unused protected flags using vmApiF1. 178 * Set Alignment flags if specified. 179 * If location specified Then Set location specific and arena flags correctly. 180 * Else set the location any flag. 181 * Determin SEL Flags. 182 */ 129 183 hMTE = VMGetOwner(ulCS, ulEIP); 184 185 cbCommit = flFlags & PAG_COMMIT ? cb : 0; 186 187 flVMFlags = VMA_USER | VMA_ZEROFILL | VMA_LOWMEM2 | VMA_ARENAPRIVATE /* 0x02010084*/ 188 | ((flFlags & OBJ_ANY) && pahvmhShr ? VMA_ARENAHIGHA : VMA_SELALLOC | VMA_ALIGNSEL) 189 | vmApiF0[flFlags & (PAG_READ | PAG_WRITE | PAG_EXECUTE | PAG_GUARD)] 190 | vmApiF1[(flFlags & (PAG_COMMIT | PAG_DECOMMIT | OBJ_TILE | OBJ_PROTECTED)) >> 4]; 191 192 if ( (flVMFlags & VMA_SELALLOC) 193 || (flFlags & OBJ_ALIGNMASK) == OBJ_ALIGN64K) 194 flVMFlags |= VMA_ALIGNSEL; 195 else if ((flFlags & OBJ_ALIGNMASK) == OBJ_ALIGNPAGE) 196 flVMFlags |= VMA_ALIGNPAGE; 197 198 if (flFlags & OBJ_LOCATION) 199 { 200 flVMFlags |= VMA_LOCSPECIFIC; 201 if (vmac.ac_va < 0x20000000) 202 flVMFlags &= ~VMA_ARENAHIGHA; 203 } 204 else 205 flVMFlags |= VMA_LOCANY; 206 207 flSelFlags = 0; 208 if (flVMFlags & VMA_SELALLOC) 209 flSelFlags = SELAF_SELMAP | SELAF_DPL3 | /* 0x0460 */ 210 (flVMFlags & VMA_WRITE ? SELAF_WRITE : 0); 211 212 213 /** @sketch 214 * Call VMAllocMem. 215 * If success Then 216 * Try set return variable. 217 * Free Memory on failure and return rc from previous operation. 218 * Endif 219 * Return return code. 220 */ 221 kprintf(("k32AllocMemEx: cb=0x%08x flVMFlags=0x%08x flSelFlags=0x%08x, hMTE=%04d vmac.ac_va=0x%08x\n", 222 cb, flVMFlags, flSelFlags, hMTE, vmac.ac_va)); 130 223 rc = VMAllocMem(cb, 131 224 cbCommit, 132 fl ag,225 flVMFlags, 133 226 0, 134 227 0, 135 228 hMTE, 136 fl Flags2,229 flSelFlags, 137 230 0, 138 231 (PVMAC)SSToDS(&vmac)); 139 232 233 if (rc == NO_ERROR) 234 { 235 rc = TKSuULongNF(ppv, SSToDS(&vmac.ac_va)); 236 if (rc) 237 { 238 kprintf(("k32AllocMemEx: Failed to set *ppv. rc=%d\n", rc)); 239 VMFreeMem(vmac.ac_va, 0, 0); 240 } 241 } 242 else 243 kprintf(("k32AllocMemEx: VMAllocMem failed with rc=%d\n", rc)); 244 245 kprintf(("k32AllocMemEx: returns rc=%d (*ppv=0x%08x)\n", rc, vmac.ac_va)); 140 246 return rc; 141 #else142 NOREF(ppv);143 NOREF(cb);144 NOREF(flag);145 NOREF(ulCS);146 NOREF(ulEIP);147 return ERROR_NOT_SUPPORTED;148 #endif149 247 } 150 248
Note:
See TracChangeset
for help on using the changeset viewer.