2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis and Cameron Heide
12 #include <sys/types.h>
23 #ifndef PROT_NONE /* FreeBSD doesn't define PROT_NONE */
32 typedef struct _VRANGE_OBJECT
36 struct _VRANGE_OBJECT
*next
;
39 virtual_mem_t
*mem
= 0;
43 /*******************************************************************
45 * A VRANGE denotes a contiguous part of the address space. It is used
46 * for house keeping, and will be obtained by higher-level memory allocation
47 * functions (VirtualAlloc, MapViewOfFile)
48 * There can be at most one VRANGE object covering any address at any time.
49 * Currently, all VRANGE objects are stored in a sorted list. Wine does not
50 * attempt to give a complete list of in-use address ranges, only those
51 * allocated via Win32.
52 * An exception is IsVrangeFree, which should test the OS specific
53 * mappings, too. As a default, an range not known to be allocated is
55 *******************************************************************/
57 VRANGE_OBJECT
*MEMORY_ranges
=0;
59 VRANGE_OBJECT
*MEMORY_FindVrange(DWORD start
)
62 for(range
=MEMORY_ranges
;range
&& range
->start
<start
;range
=range
->next
)
64 if(range
->start
<start
&& start
<range
->start
+range
->size
)
70 static int MEMORY_IsVrangeFree(DWORD start
,DWORD size
)
76 /* First, check our lists*/
78 for(range
=MEMORY_ranges
;range
&& range
->start
<start
;range
=range
->next
)
80 if((range
->start
<start
&& start
<range
->start
+range
->size
) ||
81 (range
->start
<end
&& end
<range
->start
+range
->size
))
84 /* Now, check the maps that are not under our control */
87 FILE *f
=fopen("/proc/self/maps","r");
94 if(!fgets(line
,sizeof(line
),f
))
97 lower
=strtoul(it
,&it
,16);
99 fprintf(stderr
,"Format of /proc/self/maps changed\n");
100 upper
=strtoul(it
,&it
,16);
101 if((lower
<start
&& start
<upper
) || (lower
<start
+size
&& start
+size
<upper
))
115 fprintf(stdnimp
, "Don't know how to perform MEMORY_IsVrangeFree on "
116 "this system.\n Please fix\n");
124 /* FIXME: might need to consolidate ranges */
125 void MEMORY_InsertVrange(VRANGE_OBJECT
*r
)
127 VRANGE_OBJECT
*it
,*last
;
128 if(!MEMORY_ranges
|| r
->start
<MEMORY_ranges
->start
)
130 r
->next
=MEMORY_ranges
;
133 for(it
=MEMORY_ranges
,last
=0;it
&& it
->start
<r
->start
;it
=it
->next
)
140 VRANGE_OBJECT
*MEMORY_AllocVrange(int start
,int size
)
142 VRANGE_OBJECT
*ret
=HeapAlloc( SystemHeap
, 0, sizeof(VRANGE_OBJECT
));
143 MEMORY_InsertVrange(ret
);
147 void MEMORY_ReleaseVrange(VRANGE_OBJECT
*r
)
152 MEMORY_ranges
=r
->next
;
153 HeapFree( SystemHeap
, 0, r
);
156 for(it
=MEMORY_ranges
;it
;it
=it
->next
)
157 if(it
->next
==r
)break;
160 fprintf(stderr
,"VRANGE not found\n");
164 HeapFree( SystemHeap
, 0, r
);
167 /***********************************************************************
168 * VirtualAlloc (KERNEL32.548)
170 int TranslateProtectionFlags(DWORD
);
171 LPVOID
VirtualAlloc(LPVOID lpvAddress
, DWORD cbSize
,
172 DWORD fdwAllocationType
, DWORD fdwProtect
)
176 virtual_mem_t
*tmp_mem
;
178 static int fdzero
= -1;
182 if ((fdzero
= open( "/dev/zero", O_RDONLY
)) == -1)
184 perror( "/dev/zero: open" );
189 dprintf_win32(stddeb
, "VirtualAlloc: size = %ld, address=%p\n", cbSize
, lpvAddress
);
190 if (fdwAllocationType
& MEM_RESERVE
|| !lpvAddress
) {
191 ptr
= mmap((void *)((((unsigned long)lpvAddress
-1) & 0xFFFF0000L
)
193 cbSize
, PROT_NONE
, MAP_PRIVATE
, fdzero
, 0 );
194 if (ptr
== (caddr_t
) -1) {
195 dprintf_win32(stddeb
, "VirtualAlloc: returning NULL");
196 return (LPVOID
) NULL
;
198 if (lpvAddress
&& ((unsigned long)ptr
& 0xFFFF0000L
)) {
201 ptr
= mmap(lpvAddress
, cbSize
,
202 PROT_NONE
, MAP_PRIVATE
, fdzero
, 0 );
203 if (ptr
== (caddr_t
) -1) {
204 dprintf_win32(stddeb
, "VirtualAlloc: returning NULL");
205 return (LPVOID
) NULL
;
207 ptr
= (void *)((((unsigned long)ptr
-1) & 0xFFFF0000L
)+0x00010000L
);
209 /* remember the size for VirtualFree since it's going to be handed
212 if (mem_count
== mem_used
) {
213 tmp_mem
= realloc(mem
,(mem_count
+10)*sizeof(virtual_mem_t
));
214 if (!tmp_mem
) return 0;
216 memset(mem
+mem_count
, 0, 10*sizeof(virtual_mem_t
));
219 for (i
=0; i
<mem_count
; i
++) {
222 (mem
+i
)->size
= cbSize
;
231 if (fdwAllocationType
& MEM_COMMIT
) {
232 prot
= TranslateProtectionFlags(fdwProtect
&
233 ~(PAGE_GUARD
| PAGE_NOCACHE
));
234 mprotect(ptr
, cbSize
, prot
);
237 /* kludge for gnu-win32 */
238 if (fdwAllocationType
& MEM_RESERVE
) return sbrk(0);
239 ptr
= malloc(cbSize
+ 65536);
242 /* Round it up to the next 64K boundary and zero it.
244 ptr
= (void *)(((unsigned long)ptr
& 0xFFFF0000L
) + 0x00010000L
);
245 memset(ptr
, 0, cbSize
);
248 dprintf_win32(stddeb
, "VirtualAlloc: got pointer %p\n", ptr
);
252 /***********************************************************************
253 * VirtualFree (KERNEL32.550)
255 BOOL32
VirtualFree(LPVOID lpvAddress
, DWORD cbSize
, DWORD fdwFreeType
)
259 if (fdwFreeType
& MEM_RELEASE
) {
260 for (i
=0; i
<mem_count
; i
++) {
261 if ((mem
+i
)->ptr
== lpvAddress
) {
262 munmap(lpvAddress
, (mem
+i
)->size
);
269 mprotect(lpvAddress
, cbSize
, PROT_NONE
);
278 /***********************************************************************
279 * VirtualQuery (KERNEL32.554)
281 BOOL32
VirtualQuery(LPCVOID address
,LPMEMORY_BASIC_INFORMATION buf
,DWORD len
)
283 /* FIXME: fill out structure ... */
287 /***********************************************************************
288 * VirtualProtect (KERNEL32.552)
290 BOOL32
VirtualProtect(LPVOID lpAddress
,DWORD dwSize
,DWORD flNewProtect
,LPDWORD lpflOldProtect
) {
291 /* FIXME: do protection ... see mprotect(). */
296 int TranslateProtectionFlags(DWORD protection_flags
)
300 switch(protection_flags
) {
305 prot
=PROT_READ
|PROT_WRITE
;
313 case PAGE_EXECUTE_READ
:
314 prot
=PROT_EXEC
|PROT_READ
;
316 case PAGE_EXECUTE_READWRITE
:
317 prot
=PROT_EXEC
|PROT_READ
|PROT_WRITE
;
319 case PAGE_EXECUTE_WRITECOPY
:
320 prot
=PROT_EXEC
|PROT_WRITE
;
331 /******************************************************************
334 BOOL
WIN32_IsBadReadPtr(void* ptr
, unsigned int bytes
)
336 dprintf_global(stddeb
,"IsBadReadPtr(%x,%x)\n",(int)ptr
,bytes
);
337 /* FIXME: Should make check based on actual mappings, here */
341 /******************************************************************
344 BOOL
WIN32_IsBadWritePtr(void* ptr
, unsigned int bytes
)
346 dprintf_global(stddeb
,"IsBadWritePtr(%x,%x)\n",(int)ptr
,bytes
);
347 /* FIXME: Should make check based on actual mappings, here */
350 /******************************************************************
353 BOOL
WIN32_IsBadCodePtr(void* ptr
, unsigned int bytes
)
355 dprintf_global(stddeb
,"IsBadCodePtr(%x,%x)\n",(int)ptr
,bytes
);
356 /* FIXME: Should make check based on actual mappings, here */