2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis and Cameron Heide
22 #ifndef PROT_NONE /* FreeBSD doesn't define PROT_NONE */
31 virtual_mem_t
*mem
= 0;
35 /*******************************************************************
37 * A VRANGE denotes a contiguous part of the address space. It is used
38 * for house keeping, and will be obtained by higher-level memory allocation
39 * functions (VirtualAlloc, MapViewOfFile)
40 * There can be at most one VRANGE object covering any address at any time.
41 * Currently, all VRANGE objects are stored in a sorted list. Wine does not
42 * attempt to give a complete list of in-use address ranges, only those
43 * allocated via Win32.
44 * An exception is IsVrangeFree, which should test the OS specific
45 * mappings, too. As a default, an range not known to be allocated is
47 *******************************************************************/
49 VRANGE_OBJECT
*MEMORY_ranges
=0;
51 VRANGE_OBJECT
*MEMORY_FindVrange(DWORD start
)
54 for(range
=MEMORY_ranges
;range
&& range
->start
<start
;range
=range
->next
)
56 if(range
->start
<start
&& start
<range
->start
+range
->size
)
62 static int MEMORY_IsVrangeFree(DWORD start
,DWORD size
)
68 /* First, check our lists*/
70 for(range
=MEMORY_ranges
;range
&& range
->start
<start
;range
=range
->next
)
72 if((range
->start
<start
&& start
<range
->start
+range
->size
) ||
73 (range
->start
<end
&& end
<range
->start
+range
->size
))
76 /* Now, check the maps that are not under our control */
79 FILE *f
=fopen("/proc/self/maps","r");
86 if(!fgets(line
,sizeof(line
),f
))
89 lower
=strtoul(it
,&it
,16);
91 fprintf(stderr
,"Format of /proc/self/maps changed\n");
92 upper
=strtoul(it
,&it
,16);
93 if((lower
<start
&& start
<upper
) || (lower
<start
+size
&& start
+size
<upper
))
107 fprintf(stdnimp
, "Don't know how to perform MEMORY_IsVrangeFree on "
108 "this system.\n Please fix\n");
116 /* FIXME: might need to consolidate ranges */
117 void MEMORY_InsertVrange(VRANGE_OBJECT
*r
)
119 VRANGE_OBJECT
*it
,*last
;
120 if(!MEMORY_ranges
|| r
->start
<MEMORY_ranges
->start
)
122 r
->next
=MEMORY_ranges
;
125 for(it
=MEMORY_ranges
,last
=0;it
&& it
->start
<r
->start
;it
=it
->next
)
132 VRANGE_OBJECT
*MEMORY_AllocVrange(int start
,int size
)
134 VRANGE_OBJECT
*ret
=CreateKernelObject(sizeof(VRANGE_OBJECT
));
135 ret
->common
.magic
=KERNEL_OBJECT_VRANGE
;
136 MEMORY_InsertVrange(ret
);
140 void MEMORY_ReleaseVrange(VRANGE_OBJECT
*r
)
145 MEMORY_ranges
=r
->next
;
146 ReleaseKernelObject(r
);
149 for(it
=MEMORY_ranges
;it
;it
=it
->next
)
150 if(it
->next
==r
)break;
153 fprintf(stderr
,"VRANGE not found\n");
157 ReleaseKernelObject(r
);
160 /***********************************************************************
161 * VirtualAlloc (KERNEL32.548)
163 int TranslateProtectionFlags(DWORD
);
164 LPVOID
VirtualAlloc(LPVOID lpvAddress
, DWORD cbSize
,
165 DWORD fdwAllocationType
, DWORD fdwProtect
)
169 virtual_mem_t
*tmp_mem
;
171 static int fdzero
= -1;
175 if ((fdzero
= open( "/dev/zero", O_RDONLY
)) == -1)
177 perror( "/dev/zero: open" );
182 dprintf_win32(stddeb
, "VirtualAlloc: size = %ld, address=%p\n", cbSize
, lpvAddress
);
183 if (fdwAllocationType
& MEM_RESERVE
|| !lpvAddress
) {
184 ptr
= mmap((void *)((((unsigned long)lpvAddress
-1) & 0xFFFF0000L
)
186 cbSize
, PROT_NONE
, MAP_PRIVATE
, fdzero
, 0 );
187 if (ptr
== (caddr_t
) -1) {
188 dprintf_win32(stddeb
, "VirtualAlloc: returning NULL");
189 return (LPVOID
) NULL
;
191 if (lpvAddress
&& ((unsigned long)ptr
& 0xFFFF0000L
)) {
194 ptr
= mmap(lpvAddress
, cbSize
,
195 PROT_NONE
, MAP_PRIVATE
, fdzero
, 0 );
196 if (ptr
== (caddr_t
) -1) {
197 dprintf_win32(stddeb
, "VirtualAlloc: returning NULL");
198 return (LPVOID
) NULL
;
200 ptr
= (void *)((((unsigned long)ptr
-1) & 0xFFFF0000L
)+0x00010000L
);
202 /* remember the size for VirtualFree since it's going to be handed
205 if (mem_count
== mem_used
) {
206 tmp_mem
= realloc(mem
,(mem_count
+10)*sizeof(virtual_mem_t
));
207 if (!tmp_mem
) return 0;
209 memset(mem
+mem_count
, 0, 10*sizeof(virtual_mem_t
));
212 for (i
=0; i
<mem_count
; i
++) {
215 (mem
+i
)->size
= cbSize
;
224 if (fdwAllocationType
& MEM_COMMIT
) {
225 prot
= TranslateProtectionFlags(fdwProtect
&
226 ~(PAGE_GUARD
| PAGE_NOCACHE
));
227 mprotect(ptr
, cbSize
, prot
);
230 /* kludge for gnu-win32 */
231 if (fdwAllocationType
& MEM_RESERVE
) return sbrk(0);
232 ptr
= malloc(cbSize
+ 65536);
235 /* Round it up to the next 64K boundary and zero it.
237 ptr
= (void *)(((unsigned long)ptr
& 0xFFFF0000L
) + 0x00010000L
);
238 memset(ptr
, 0, cbSize
);
241 dprintf_win32(stddeb
, "VirtualAlloc: got pointer %p\n", ptr
);
245 /***********************************************************************
246 * VirtualFree (KERNEL32.550)
248 BOOL32
VirtualFree(LPVOID lpvAddress
, DWORD cbSize
, DWORD fdwFreeType
)
252 if (fdwFreeType
& MEM_RELEASE
) {
253 for (i
=0; i
<mem_count
; i
++) {
254 if ((mem
+i
)->ptr
== lpvAddress
) {
255 munmap(lpvAddress
, (mem
+i
)->size
);
262 mprotect(lpvAddress
, cbSize
, PROT_NONE
);
271 /***********************************************************************
272 * VirtualQuery (KERNEL32.554)
274 BOOL32
VirtualQuery(LPCVOID address
,LPMEMORY_BASIC_INFORMATION buf
,DWORD len
)
276 /* FIXME: fill out structure ... */
280 int TranslateProtectionFlags(DWORD protection_flags
)
284 switch(protection_flags
) {
289 prot
=PROT_READ
|PROT_WRITE
;
297 case PAGE_EXECUTE_READ
:
298 prot
=PROT_EXEC
|PROT_READ
;
300 case PAGE_EXECUTE_READWRITE
:
301 prot
=PROT_EXEC
|PROT_READ
|PROT_WRITE
;
303 case PAGE_EXECUTE_WRITECOPY
:
304 prot
=PROT_EXEC
|PROT_WRITE
;
315 /******************************************************************
318 BOOL
WIN32_IsBadReadPtr(void* ptr
, unsigned int bytes
)
320 dprintf_global(stddeb
,"IsBadReadPtr(%x,%x)\n",(int)ptr
,bytes
);
321 /* FIXME: Should make check based on actual mappings, here */
325 /******************************************************************
328 BOOL
WIN32_IsBadWritePtr(void* ptr
, unsigned int bytes
)
330 dprintf_global(stddeb
,"IsBadWritePtr(%x,%x)\n",(int)ptr
,bytes
);
331 /* FIXME: Should make check based on actual mappings, here */
334 /******************************************************************
337 BOOL
WIN32_IsBadCodePtr(void* ptr
, unsigned int bytes
)
339 dprintf_global(stddeb
,"IsBadCodePtr(%x,%x)\n",(int)ptr
,bytes
);
340 /* FIXME: Should make check based on actual mappings, here */