2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis and Cameron Heide
22 #ifndef PROT_NONE /* FreeBSD doesn't define PROT_NONE */
31 typedef struct _VRANGE_OBJECT
35 struct _VRANGE_OBJECT
*next
;
38 virtual_mem_t
*mem
= 0;
42 /*******************************************************************
44 * A VRANGE denotes a contiguous part of the address space. It is used
45 * for house keeping, and will be obtained by higher-level memory allocation
46 * functions (VirtualAlloc, MapViewOfFile)
47 * There can be at most one VRANGE object covering any address at any time.
48 * Currently, all VRANGE objects are stored in a sorted list. Wine does not
49 * attempt to give a complete list of in-use address ranges, only those
50 * allocated via Win32.
51 * An exception is IsVrangeFree, which should test the OS specific
52 * mappings, too. As a default, an range not known to be allocated is
54 *******************************************************************/
56 VRANGE_OBJECT
*MEMORY_ranges
=0;
58 VRANGE_OBJECT
*MEMORY_FindVrange(DWORD start
)
61 for(range
=MEMORY_ranges
;range
&& range
->start
<start
;range
=range
->next
)
63 if(range
->start
<start
&& start
<range
->start
+range
->size
)
69 static int MEMORY_IsVrangeFree(DWORD start
,DWORD size
)
75 /* First, check our lists*/
77 for(range
=MEMORY_ranges
;range
&& range
->start
<start
;range
=range
->next
)
79 if((range
->start
<start
&& start
<range
->start
+range
->size
) ||
80 (range
->start
<end
&& end
<range
->start
+range
->size
))
83 /* Now, check the maps that are not under our control */
86 FILE *f
=fopen("/proc/self/maps","r");
93 if(!fgets(line
,sizeof(line
),f
))
96 lower
=strtoul(it
,&it
,16);
98 fprintf(stderr
,"Format of /proc/self/maps changed\n");
99 upper
=strtoul(it
,&it
,16);
100 if((lower
<start
&& start
<upper
) || (lower
<start
+size
&& start
+size
<upper
))
114 fprintf(stdnimp
, "Don't know how to perform MEMORY_IsVrangeFree on "
115 "this system.\n Please fix\n");
123 /* FIXME: might need to consolidate ranges */
124 void MEMORY_InsertVrange(VRANGE_OBJECT
*r
)
126 VRANGE_OBJECT
*it
,*last
;
127 if(!MEMORY_ranges
|| r
->start
<MEMORY_ranges
->start
)
129 r
->next
=MEMORY_ranges
;
132 for(it
=MEMORY_ranges
,last
=0;it
&& it
->start
<r
->start
;it
=it
->next
)
139 VRANGE_OBJECT
*MEMORY_AllocVrange(int start
,int size
)
141 VRANGE_OBJECT
*ret
=HeapAlloc( SystemHeap
, 0, sizeof(VRANGE_OBJECT
));
142 MEMORY_InsertVrange(ret
);
146 void MEMORY_ReleaseVrange(VRANGE_OBJECT
*r
)
151 MEMORY_ranges
=r
->next
;
152 HeapFree( SystemHeap
, 0, r
);
155 for(it
=MEMORY_ranges
;it
;it
=it
->next
)
156 if(it
->next
==r
)break;
159 fprintf(stderr
,"VRANGE not found\n");
163 HeapFree( SystemHeap
, 0, r
);
166 /***********************************************************************
167 * VirtualAlloc (KERNEL32.548)
169 int TranslateProtectionFlags(DWORD
);
170 LPVOID
VirtualAlloc(LPVOID lpvAddress
, DWORD cbSize
,
171 DWORD fdwAllocationType
, DWORD fdwProtect
)
175 virtual_mem_t
*tmp_mem
;
177 static int fdzero
= -1;
181 if ((fdzero
= open( "/dev/zero", O_RDONLY
)) == -1)
183 perror( "/dev/zero: open" );
188 dprintf_win32(stddeb
, "VirtualAlloc: size = %ld, address=%p\n", cbSize
, lpvAddress
);
189 if (fdwAllocationType
& MEM_RESERVE
|| !lpvAddress
) {
190 ptr
= mmap((void *)((((unsigned long)lpvAddress
-1) & 0xFFFF0000L
)
192 cbSize
, PROT_NONE
, MAP_PRIVATE
, fdzero
, 0 );
193 if (ptr
== (caddr_t
) -1) {
194 dprintf_win32(stddeb
, "VirtualAlloc: returning NULL");
195 return (LPVOID
) NULL
;
197 if (lpvAddress
&& ((unsigned long)ptr
& 0xFFFF0000L
)) {
200 ptr
= mmap(lpvAddress
, cbSize
,
201 PROT_NONE
, MAP_PRIVATE
, fdzero
, 0 );
202 if (ptr
== (caddr_t
) -1) {
203 dprintf_win32(stddeb
, "VirtualAlloc: returning NULL");
204 return (LPVOID
) NULL
;
206 ptr
= (void *)((((unsigned long)ptr
-1) & 0xFFFF0000L
)+0x00010000L
);
208 /* remember the size for VirtualFree since it's going to be handed
211 if (mem_count
== mem_used
) {
212 tmp_mem
= realloc(mem
,(mem_count
+10)*sizeof(virtual_mem_t
));
213 if (!tmp_mem
) return 0;
215 memset(mem
+mem_count
, 0, 10*sizeof(virtual_mem_t
));
218 for (i
=0; i
<mem_count
; i
++) {
221 (mem
+i
)->size
= cbSize
;
230 if (fdwAllocationType
& MEM_COMMIT
) {
231 prot
= TranslateProtectionFlags(fdwProtect
&
232 ~(PAGE_GUARD
| PAGE_NOCACHE
));
233 mprotect(ptr
, cbSize
, prot
);
236 /* kludge for gnu-win32 */
237 if (fdwAllocationType
& MEM_RESERVE
) return sbrk(0);
238 ptr
= malloc(cbSize
+ 65536);
241 /* Round it up to the next 64K boundary and zero it.
243 ptr
= (void *)(((unsigned long)ptr
& 0xFFFF0000L
) + 0x00010000L
);
244 memset(ptr
, 0, cbSize
);
247 dprintf_win32(stddeb
, "VirtualAlloc: got pointer %p\n", ptr
);
251 /***********************************************************************
252 * VirtualFree (KERNEL32.550)
254 BOOL32
VirtualFree(LPVOID lpvAddress
, DWORD cbSize
, DWORD fdwFreeType
)
258 if (fdwFreeType
& MEM_RELEASE
) {
259 for (i
=0; i
<mem_count
; i
++) {
260 if ((mem
+i
)->ptr
== lpvAddress
) {
261 munmap(lpvAddress
, (mem
+i
)->size
);
268 mprotect(lpvAddress
, cbSize
, PROT_NONE
);
277 /***********************************************************************
278 * VirtualQuery (KERNEL32.554)
280 BOOL32
VirtualQuery(LPCVOID address
,LPMEMORY_BASIC_INFORMATION buf
,DWORD len
)
282 /* FIXME: fill out structure ... */
286 int TranslateProtectionFlags(DWORD protection_flags
)
290 switch(protection_flags
) {
295 prot
=PROT_READ
|PROT_WRITE
;
303 case PAGE_EXECUTE_READ
:
304 prot
=PROT_EXEC
|PROT_READ
;
306 case PAGE_EXECUTE_READWRITE
:
307 prot
=PROT_EXEC
|PROT_READ
|PROT_WRITE
;
309 case PAGE_EXECUTE_WRITECOPY
:
310 prot
=PROT_EXEC
|PROT_WRITE
;
321 /******************************************************************
324 BOOL
WIN32_IsBadReadPtr(void* ptr
, unsigned int bytes
)
326 dprintf_global(stddeb
,"IsBadReadPtr(%x,%x)\n",(int)ptr
,bytes
);
327 /* FIXME: Should make check based on actual mappings, here */
331 /******************************************************************
334 BOOL
WIN32_IsBadWritePtr(void* ptr
, unsigned int bytes
)
336 dprintf_global(stddeb
,"IsBadWritePtr(%x,%x)\n",(int)ptr
,bytes
);
337 /* FIXME: Should make check based on actual mappings, here */
340 /******************************************************************
343 BOOL
WIN32_IsBadCodePtr(void* ptr
, unsigned int bytes
)
345 dprintf_global(stddeb
,"IsBadCodePtr(%x,%x)\n",(int)ptr
,bytes
);
346 /* FIXME: Should make check based on actual mappings, here */