Release 960114
[wine/gsoc-2012-control.git] / win32 / memory.c
blobbd55c2b874f5af1d221ad296ee9232b9d842e493
1 /*
2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis and Cameron Heide
5 */
7 #include <malloc.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <sys/time.h>
11 #include <unistd.h>
12 #include <sys/mman.h>
13 #include "windows.h"
14 #include "winerror.h"
15 #include "kernel32.h"
16 #include "winbase.h"
17 #include "stddebug.h"
18 #include "debug.h"
20 #ifndef PROT_NONE /* FreeBSD doesn't define PROT_NONE */
21 #define PROT_NONE 0
22 #endif
23 #ifndef MAP_ANON
24 #define MAP_ANON 0
25 #endif
27 typedef struct {
28 caddr_t ptr;
29 long size;
30 } virtual_mem_t;
32 virtual_mem_t *mem = 0;
33 int mem_count = 0;
34 int mem_used = 0;
36 /***********************************************************************
37 * VirtualAlloc (KERNEL32.548)
39 int TranslateProtectionFlags(DWORD);
40 LPVOID VirtualAlloc(LPVOID lpvAddress, DWORD cbSize,
41 DWORD fdwAllocationType, DWORD fdwProtect)
43 caddr_t ptr;
44 int i;
45 virtual_mem_t *tmp_mem;
46 int prot;
48 dprintf_win32(stddeb, "VirtualAlloc: size = %ld, address=%p\n", cbSize, lpvAddress);
49 if (fdwAllocationType & MEM_RESERVE || !lpvAddress) {
50 ptr = mmap((void *)((((unsigned long)lpvAddress-1) & 0xFFFF0000L)
51 + 0x00010000L),
52 cbSize, PROT_NONE, MAP_ANON|MAP_PRIVATE,-1,0);
53 if (ptr == (caddr_t) -1) {
54 dprintf_win32(stddeb, "VirtualAlloc: returning NULL");
55 return (LPVOID) NULL;
57 if (lpvAddress && ((unsigned long)ptr & 0xFFFF0000L)) {
58 munmap(ptr, cbSize);
59 cbSize += 65535;
60 ptr = mmap(lpvAddress, cbSize,
61 PROT_NONE, MAP_ANON|MAP_PRIVATE,-1,0);
62 if (ptr == (caddr_t) -1) {
63 dprintf_win32(stddeb, "VirtualAlloc: returning NULL");
64 return (LPVOID) NULL;
66 ptr = (void *)((((unsigned long)ptr-1) & 0xFFFF0000L)+0x00010000L);
68 /* remember the size for VirtualFree since it's going to be handed
69 a zero len */
70 if (ptr) {
71 if (mem_count == mem_used) {
72 tmp_mem = realloc(mem,(mem_count+10)*sizeof(virtual_mem_t));
73 if (!tmp_mem) return 0;
74 mem = tmp_mem;
75 memset(mem+mem_count, 0, 10*sizeof(virtual_mem_t));
76 mem_count += 10;
78 for (i=0; i<mem_count; i++) {
79 if (!(mem+i)->ptr) {
80 (mem+i)->ptr = ptr;
81 (mem+i)->size = cbSize;
82 mem_used++;
83 break;
87 } else {
88 ptr = lpvAddress;
90 if (fdwAllocationType & MEM_COMMIT) {
91 prot = TranslateProtectionFlags(fdwProtect &
92 ~(PAGE_GUARD | PAGE_NOCACHE));
93 mprotect(ptr, cbSize, prot);
95 #if 0
96 /* kludge for gnu-win32 */
97 if (fdwAllocationType & MEM_RESERVE) return sbrk(0);
98 ptr = malloc(cbSize + 65536);
99 if(ptr)
101 /* Round it up to the next 64K boundary and zero it.
103 ptr = (void *)(((unsigned long)ptr & 0xFFFF0000L) + 0x00010000L);
104 memset(ptr, 0, cbSize);
106 #endif
107 dprintf_win32(stddeb, "VirtualAlloc: got pointer %p\n", ptr);
108 return ptr;
111 /***********************************************************************
112 * VirtualFree (KERNEL32.550)
114 BOOL VirtualFree(LPVOID lpvAddress, DWORD cbSize, DWORD fdwFreeType)
116 int i;
118 if (fdwFreeType & MEM_RELEASE) {
119 for (i=0; i<mem_count; i++) {
120 if ((mem+i)->ptr == lpvAddress) {
121 munmap(lpvAddress, (mem+i)->size);
122 (mem+i)->ptr = 0;
123 mem_used--;
124 break;
127 } else {
128 mprotect(lpvAddress, cbSize, PROT_NONE);
130 #if 0
131 if(lpvAddress)
132 free(lpvAddress);
133 #endif
134 return 1;
137 int TranslateProtectionFlags(DWORD protection_flags)
139 int prot;
141 switch(protection_flags) {
142 case PAGE_READONLY:
143 prot=PROT_READ;
144 break;
145 case PAGE_READWRITE:
146 prot=PROT_READ|PROT_WRITE;
147 break;
148 case PAGE_WRITECOPY:
149 prot=PROT_WRITE;
150 break;
151 case PAGE_EXECUTE:
152 prot=PROT_EXEC;
153 break;
154 case PAGE_EXECUTE_READ:
155 prot=PROT_EXEC|PROT_READ;
156 break;
157 case PAGE_EXECUTE_READWRITE:
158 prot=PROT_EXEC|PROT_READ|PROT_WRITE;
159 break;
160 case PAGE_EXECUTE_WRITECOPY:
161 prot=PROT_EXEC|PROT_WRITE;
162 break;
163 case PAGE_NOACCESS:
164 default:
165 prot=PROT_NONE;
166 break;
168 return prot;