source: trunk/src/kernel32/virtual.cpp@ 8706

Last change on this file since 8706 was 8457, checked in by sandervl, 23 years ago

more logging

File size: 27.4 KB
Line 
1/* $Id: virtual.cpp,v 1.44 2002-05-20 13:48:50 sandervl Exp $ */
2
3/*
4 * Win32 virtual memory functions
5 *
6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1998 Knut St. Osmundsen
8 * Copyright 1998 Peter FitzSimmons
9 *
10 * Parts (VIRTUAL_MapFileA/W) based on Wine code (memory\virtual.c):
11 *
12 * Copyright 1997 Alexandre Julliard
13 *
14 * Project Odin Software License can be found in LICENSE.TXT
15 *
16 */
17
18#include <odin.h>
19#include <odinwrap.h>
20
21#include <os2win.h>
22#include <stdlib.h>
23#include <string.h>
24#include <win\virtual.h>
25#include <heapstring.h>
26#include <handlemanager.h>
27#include "mmap.h"
28#include "oslibdos.h"
29
30#define DBG_LOCALLOG DBG_virtual
31#include "dbglocal.h"
32
33ODINDEBUGCHANNEL(KERNEL32-VIRTUAL)
34
35#define PAGE_SHIFT 12
36
37/***********************************************************************
38 * CreateFileMapping32A (KERNEL32.46)
39 * Creates a named or unnamed file-mapping object for the specified file
40 *
41 * RETURNS
42 * Handle: Success
43 * 0: Mapping object does not exist
44 * NULL: Failure
45 */
46HANDLE WINAPI CreateFileMappingA(
47 HFILE hFile, /* [in] Handle of file to map */
48 SECURITY_ATTRIBUTES *sa, /* [in] Optional security attributes*/
49 DWORD protect, /* [in] Protection for mapping object */
50 DWORD size_high, /* [in] High-order 32 bits of object size */
51 DWORD size_low, /* [in] Low-order 32 bits of object size */
52 LPCSTR name /* [in] Name of file-mapping object */ )
53{
54 HANDLE hFileMap;
55
56 dprintf(("CreateFileMappingA: %x %x %x%x %s", hFile, protect, size_high, size_low, name));
57 hFileMap = HMCreateFileMapping(hFile, sa, protect, size_high, size_low, name);
58 dprintf(("CreateFileMappingA returned %x", hFileMap));
59 return hFileMap;
60}
61
62
63/***********************************************************************
64 * CreateFileMapping32W (KERNEL32.47)
65 * See CreateFileMapping32A
66 */
67HANDLE WINAPI CreateFileMappingW( HFILE hFile, LPSECURITY_ATTRIBUTES attr,
68 DWORD protect, DWORD size_high,
69 DWORD size_low, LPCWSTR name )
70{
71 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
72 HANDLE ret = CreateFileMappingA( hFile, attr, protect,
73 size_high, size_low, nameA );
74 HeapFree( GetProcessHeap(), 0, nameA );
75 return ret;
76}
77
78
79/***********************************************************************
80 * OpenFileMapping32A (KERNEL32.397)
81 * Opens a named file-mapping object.
82 *
83 * RETURNS
84 * Handle: Success
85 * NULL: Failure
86 */
87HANDLE WINAPI OpenFileMappingA(
88 DWORD access, /* [in] Access mode */
89 BOOL inherit, /* [in] Inherit flag */
90 LPCSTR name ) /* [in] Name of file-mapping object */
91{
92 dprintf(("OpenFileMappingA: %x %d %s", access, inherit, name));
93 return HMOpenFileMapping(access, inherit, name);
94}
95
96
97/***********************************************************************
98 * OpenFileMapping32W (KERNEL32.398)
99 * See OpenFileMapping32A
100 */
101HANDLE WINAPI OpenFileMappingW( DWORD access, BOOL inherit, LPCWSTR name)
102{
103 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
104 HANDLE ret = OpenFileMappingA( access, inherit, nameA );
105 HeapFree( GetProcessHeap(), 0, nameA );
106 return ret;
107}
108
109
110/***********************************************************************
111 * MapViewOfFile (KERNEL32.385)
112 * Maps a view of a file into the address space
113 *
114 * RETURNS
115 * Starting address of mapped view
116 * NULL: Failure
117 */
118LPVOID WINAPI MapViewOfFile(
119 HANDLE mapping, /* [in] File-mapping object to map */
120 DWORD access, /* [in] Access mode */
121 DWORD offset_high, /* [in] High-order 32 bits of file offset */
122 DWORD offset_low, /* [in] Low-order 32 bits of file offset */
123 DWORD count /* [in] Number of bytes to map */
124)
125{
126 return MapViewOfFileEx( mapping, access, offset_high,
127 offset_low, count, NULL );
128}
129
130
131/***********************************************************************
132 * MapViewOfFileEx (KERNEL32.386)
133 * Maps a view of a file into the address space
134 *
135 * RETURNS
136 * Starting address of mapped view
137 * NULL: Failure
138 */
139LPVOID WINAPI MapViewOfFileEx(
140 HANDLE handle, /* [in] File-mapping object to map */
141 DWORD access, /* [in] Access mode */
142 DWORD offset_high, /* [in] High-order 32 bits of file offset */
143 DWORD offset_low, /* [in] Low-order 32 bits of file offset */
144 DWORD count, /* [in] Number of bytes to map */
145 LPVOID addr /* [in] Suggested starting address for mapped view */
146)
147{
148 return HMMapViewOfFileEx(handle, access, offset_high, offset_low, count, addr);
149}
150
151
152/***********************************************************************
153 * FlushViewOfFile (KERNEL32.262)
154 * Writes to the disk a byte range within a mapped view of a file
155 *
156 * RETURNS
157 * TRUE: Success
158 * FALSE: Failure
159 */
160BOOL WINAPI FlushViewOfFile(
161 LPCVOID base, /* [in] Start address of byte range to flush */
162 DWORD cbFlush /* [in] Number of bytes in range */
163)
164{
165 Win32MemMap *map;
166 DWORD offset;
167
168 if (!base)
169 {
170 SetLastError( ERROR_INVALID_PARAMETER );
171 return FALSE;
172 }
173 map = Win32MemMapView::findMapByView((ULONG)base, &offset, MEMMAP_ACCESS_READ);
174 if(map == NULL) {
175 SetLastError( ERROR_FILE_NOT_FOUND );
176 return FALSE;
177 }
178 return map->flushView(offset, cbFlush);
179}
180
181
182/***********************************************************************
183 * UnmapViewOfFile (KERNEL32.540)
184 * Unmaps a mapped view of a file.
185 *
186 * NOTES
187 * Should addr be an LPCVOID?
188 *
189 * RETURNS
190 * TRUE: Success
191 * FALSE: Failure
192 */
193BOOL WINAPI UnmapViewOfFile(LPVOID addr /* [in] Address where mapped view begins */
194)
195{
196 Win32MemMap *map;
197 Win32MemMapView *view;
198
199 DWORD offset;
200
201 if (!addr)
202 {
203 SetLastError( ERROR_INVALID_PARAMETER );
204 return FALSE;
205 }
206 map = Win32MemMapView::findMapByView((ULONG)addr, &offset, MEMMAP_ACCESS_READ, &view);
207 if(map == NULL) {
208 SetLastError( ERROR_FILE_NOT_FOUND );
209 return FALSE;
210 }
211 return map->unmapViewOfFile(view);
212}
213
214/***********************************************************************
215 * VIRTUAL_MapFileW
216 *
217 * Helper function to map a file to memory:
218 * name - file name
219 * [RETURN] ptr - pointer to mapped file
220 */
221HANDLE WINAPI VIRTUAL_MapFileW( LPCWSTR name , LPVOID *lpMapping, BOOL fReadIntoMemory)
222{
223 HANDLE hFile, hMapping = -1;
224
225 hFile = CreateFileW( name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
226 OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0);
227 if (hFile != INVALID_HANDLE_VALUE)
228 {
229 hMapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY | ((fReadIntoMemory) ? SEC_COMMIT : 0), 0, 0, NULL );
230 CloseHandle( hFile );
231 if (hMapping)
232 {
233 *lpMapping = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
234 }
235 }
236 return hMapping;
237}
238
239/***********************************************************************
240 * VIRTUAL_MapFileA
241 *
242 * Helper function to map a file to memory:
243 * name - file name
244 * [RETURN] ptr - pointer to mapped file
245 */
246HANDLE WINAPI VIRTUAL_MapFileA( LPCSTR name , LPVOID *lpMapping, BOOL fReadIntoMemory)
247{
248 HANDLE hFile, hMapping = -1;
249
250 hFile = CreateFileA(name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
251 OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0);
252 if (hFile != INVALID_HANDLE_VALUE)
253 {
254 hMapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY | ((fReadIntoMemory) ? SEC_COMMIT : 0), 0, 0, NULL );
255 CloseHandle( hFile );
256 if (hMapping)
257 {
258 *lpMapping = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
259 }
260 }
261 return hMapping;
262}
263
264//******************************************************************************
265//******************************************************************************
266LPVOID WIN32API VirtualAlloc(LPVOID lpvAddress,
267 DWORD cbSize,
268 DWORD fdwAllocationType,
269 DWORD fdwProtect)
270{
271 PVOID Address = lpvAddress;
272 ULONG flag = 0, base;
273 DWORD rc;
274
275 SetLastError(ERROR_SUCCESS);
276
277 if (cbSize > 0x7fc00000) /* 2Gb - 4Mb */
278 {
279 dprintf(("VirtualAlloc: size too large"));
280 SetLastError( ERROR_OUTOFMEMORY );
281 return NULL;
282 }
283
284 if (!(fdwAllocationType & (MEM_COMMIT | MEM_RESERVE)) ||
285 (fdwAllocationType & ~(MEM_COMMIT | MEM_RESERVE)))
286 {
287 dprintf(("VirtualAlloc: Invalid parameter"));
288 SetLastError( ERROR_INVALID_PARAMETER );
289 return NULL;
290 }
291
292 if(fdwAllocationType & MEM_COMMIT)
293 {
294 dprintf(("VirtualAlloc: commit\n"));
295 flag = PAG_COMMIT;
296 }
297
298 if(fdwAllocationType & MEM_RESERVE) {
299 //SvL: DosRead crashes if memory is initially reserved with write
300 // access disabled (OS/2 bug) even if the commit sets the page
301 // flags to read/write:
302 // DosSetMem does not alter the 16 bit selectors so if you change memory
303 // attributes and then access the memory with a 16 bit API (such as DosRead),
304 // it will have the old (alloc time) attributes
305 flag |= PAG_READ|PAG_WRITE;
306 }
307 if(fdwProtect & PAGE_READONLY) flag |= PAG_READ;
308 if(fdwProtect & PAGE_NOACCESS) flag |= PAG_READ; //can't do this in OS/2
309 if(fdwProtect & PAGE_READWRITE) flag |= (PAG_READ | PAG_WRITE);
310 if(fdwProtect & PAGE_WRITECOPY) flag |= (PAG_READ | PAG_WRITE);
311
312 if(fdwProtect & PAGE_EXECUTE_READWRITE) flag |= (PAG_EXECUTE | PAG_WRITE | PAG_READ);
313 if(fdwProtect & PAGE_EXECUTE_READ) flag |= (PAG_EXECUTE | PAG_READ);
314 if(fdwProtect & PAGE_EXECUTE) flag |= PAG_EXECUTE;
315
316 if(fdwProtect & PAGE_GUARD) {
317 dprintf(("ERROR: PAGE_GUARD bit set for VirtualAlloc -> we don't support this right now!"));
318 flag |= PAG_GUARD;
319 }
320
321 //just do this if other options are used
322 if(!(flag & (PAG_READ | PAG_WRITE | PAG_EXECUTE)) || flag == 0)
323 {
324 dprintf(("VirtualAlloc: Unknown protection flags, default to read/write"));
325 flag |= PAG_READ | PAG_WRITE;
326 }
327
328 if(lpvAddress)
329 {
330 Win32MemMap *map;
331 ULONG offset, nrpages, accessflags = 0;
332
333 nrpages = cbSize >> PAGE_SHIFT;
334 if(cbSize & 0xFFF)
335 nrpages++;
336
337 if(flag & PAG_READ) {
338 accessflags |= MEMMAP_ACCESS_READ;
339 }
340 if(flag & PAG_WRITE) {
341 accessflags |= MEMMAP_ACCESS_WRITE;
342 }
343 if(flag & PAG_EXECUTE) {
344 accessflags |= MEMMAP_ACCESS_EXECUTE;
345 }
346 map = Win32MemMapView::findMapByView((ULONG)lpvAddress, &offset, accessflags);
347 if(map) {
348 //TODO: We don't allow protection flag changes for mmaped files now
349 map->commitPage(offset, FALSE, nrpages);
350 return lpvAddress;
351 }
352 }
353
354 // commit memory
355 if(fdwAllocationType & MEM_COMMIT)
356 {
357 Address = lpvAddress;
358
359 rc = OSLibDosSetMem(lpvAddress, cbSize, flag);
360
361 //might try to commit larger part with same base address
362 if(rc == OSLIB_ERROR_ACCESS_DENIED && cbSize > 4096 )
363 { //knut: AND more than one page
364 char *newbase = (char *)lpvAddress + ((cbSize-1) & 0xFFFFF000); //knut: lets not start after the last page!
365 ULONG size, os2flags;
366
367 while(newbase >= (char *)lpvAddress)
368 { //knut: should check first page to!!
369 size = 4096;
370 os2flags = 0;
371 rc = OSLibDosQueryMem(newbase, &size, &os2flags);
372 if(rc)
373 break;
374
375 if(os2flags & PAG_COMMIT)
376 {
377 newbase += 4096;
378 break;
379 }
380 newbase -= 4096;
381 }
382
383 if(rc == 0)
384 {
385 //In case it wants to commit bytes that fall into the last
386 //page of the previous commit command
387 if(cbSize > ((int)newbase - (int)lpvAddress))
388 rc = OSLibDosSetMem(newbase, cbSize - ((int)newbase - (int)lpvAddress), flag);
389 }
390 else return(NULL);
391
392 }
393 else
394 {
395 if(rc == OSLIB_ERROR_INVALID_ADDRESS) {
396 rc = OSLibDosAllocMem(&Address, cbSize, flag );
397 }
398 else {
399 if(rc) {
400 //check if the app tries to commit an already commited part of memory or change the protection flags
401 ULONG size = cbSize, os2flags, newrc;
402 newrc = OSLibDosQueryMem(lpvAddress, &size, &os2flags);
403 if(newrc == 0) {
404 if(size >= cbSize && (os2flags & PAG_COMMIT)) {
405 dprintf(("VirtualAlloc: commit on committed memory"));
406 if((flag & (PAG_READ|PAG_WRITE|PAG_EXECUTE)) != (os2flags & (PAG_READ|PAG_WRITE|PAG_EXECUTE)))
407 { //change protection flags
408 DWORD tmp;
409 if(VirtualProtect(lpvAddress, cbSize, fdwProtect, &tmp) == TRUE) {
410 return lpvAddress;
411 }
412 dprintf(("ERROR: VirtualAlloc: commit on committed memory -> VirtualProtect failed!!"));
413 return NULL;
414 }
415 //else everything ok
416 return lpvAddress;
417 }
418 else dprintf(("Unexpected DosSetMem error %x", rc));
419 }
420 else {
421 dprintf(("Unexpected DosQueryMem error %x", newrc));
422 }
423 }
424 }
425 }
426 }
427 else
428 {
429 rc = OSLibDosAllocMem(&Address, cbSize, flag);
430 }
431
432 if(rc)
433 {
434 dprintf(("DosSetMem returned %d\n", rc));
435 SetLastError( ERROR_OUTOFMEMORY );
436 return(NULL);
437 }
438
439 dprintf(("VirtualAlloc returned %X\n", Address));
440 return(Address);
441}
442//******************************************************************************
443//******************************************************************************
444BOOL WIN32API VirtualFree(LPVOID lpvAddress,
445 DWORD cbSize,
446 DWORD FreeType)
447{
448 DWORD rc;
449
450 SetLastError(ERROR_SUCCESS);
451
452 // verify parameters
453 if ( (FreeType & MEM_RELEASE) && (cbSize != 0) )
454 {
455 dprintf(("WARNING: VirtualFree: invalid parameter!!"));
456 SetLastError(ERROR_INVALID_PARAMETER);
457 return(FALSE);
458 }
459
460 if ( (FreeType & MEM_DECOMMIT) &&
461 (FreeType & MEM_RELEASE) )
462 {
463 dprintf(("WARNING: VirtualFree: invalid parameter!!"));
464 SetLastError(ERROR_INVALID_PARAMETER);
465 return(FALSE);
466 }
467
468 // decommit memory
469 if (FreeType & MEM_DECOMMIT)
470 {
471 // decommit memory block
472 rc = OSLibDosSetMem(lpvAddress, cbSize, PAG_DECOMMIT);
473 if(rc)
474 {
475 if(rc == 32803) { //SvL: ERROR_ALIAS
476 dprintf(("KERNEL32:VirtualFree:OsLibSetMem rc = #%d; app tries to decommit aliased memory; ignore", rc));
477 return(TRUE);
478 }
479 dprintf(("KERNEL32:VirtualFree:OsLibSetMem rc = #%d\n", rc));
480 SetLastError(ERROR_INVALID_ADDRESS);
481 return(FALSE);
482 }
483 }
484
485 // release memory
486 if (FreeType & MEM_RELEASE)
487 {
488 rc = OSLibDosFreeMem(lpvAddress); // free the memory block
489 if(rc)
490 {
491 dprintf(("KERNEL32:VirtualFree:OsLibFreeMem rc = #%d\n",
492 rc));
493 SetLastError(ERROR_INVALID_ADDRESS);
494 return(FALSE);
495 }
496 }
497
498 return(TRUE);
499}
500//******************************************************************************
501//LPVOID lpvAddress; /* address of region of committed pages */
502//DWORD cbSize; /* size of the region */
503//DWORD fdwNewProtect; /* desired access protection */
504//PDWORD pfdwOldProtect; /* address of variable to get old protection */
505//TODO: Not 100% complete
506//TODO: SetLastError on failure
507//******************************************************************************
508
509BOOL WIN32API VirtualProtect(LPVOID lpvAddress,
510 DWORD cbSize,
511 DWORD fdwNewProtect,
512 DWORD* pfdwOldProtect)
513{
514 DWORD rc;
515 DWORD cb = cbSize;
516 ULONG pageFlags = 0;
517 int npages;
518
519 if(pfdwOldProtect == NULL) {
520 dprintf(("WARNING: pfdwOldProtect == NULL"));
521 SetLastError(ERROR_INVALID_PARAMETER);
522 return(FALSE);
523 }
524
525 SetLastError(ERROR_SUCCESS);
526
527 rc = OSLibDosQueryMem(lpvAddress, &cb, &pageFlags);
528 if(rc) {
529 dprintf(("DosQueryMem returned %d\n", rc));
530 return(FALSE);
531 }
532 dprintf(("Old memory flags %X\n", pageFlags));
533 *pfdwOldProtect = 0;
534 if(pageFlags & PAG_READ && !(pageFlags & PAG_WRITE))
535 *pfdwOldProtect |= PAGE_READONLY;
536 if(pageFlags & (PAG_WRITE))
537 *pfdwOldProtect |= PAGE_READWRITE;
538
539 if((pageFlags & (PAG_WRITE | PAG_EXECUTE)) == (PAG_WRITE | PAG_EXECUTE))
540 *pfdwOldProtect |= PAGE_EXECUTE_READWRITE;
541 else
542 if(pageFlags & PAG_EXECUTE)
543 *pfdwOldProtect |= PAGE_EXECUTE_READ;
544
545 if(pageFlags & PAG_GUARD)
546 *pfdwOldProtect |= PAGE_GUARD;
547 pageFlags = 0;
548
549 if(fdwNewProtect & PAGE_READONLY) pageFlags |= PAG_READ;
550 if(fdwNewProtect & PAGE_READWRITE) pageFlags |= (PAG_READ | PAG_WRITE);
551 if(fdwNewProtect & PAGE_WRITECOPY) pageFlags |= (PAG_READ | PAG_WRITE);
552 if(fdwNewProtect & PAGE_EXECUTE_READ) pageFlags |= (PAG_EXECUTE | PAG_READ);
553 if(fdwNewProtect & PAGE_EXECUTE_READWRITE)
554 pageFlags |= (PAG_EXECUTE | PAG_WRITE | PAG_READ);
555 if(fdwNewProtect & PAGE_EXECUTE_WRITECOPY)
556 pageFlags |= (PAG_EXECUTE | PAG_WRITE | PAG_READ);
557 if(fdwNewProtect & PAGE_GUARD) pageFlags |= PAG_GUARD;
558//Not supported in OS/2??
559// if(fdwNewProtect & PAGE_NOACCESS)
560
561 dprintf(("New memory flags %X\n", pageFlags));
562 if(pageFlags == 0) {
563 dprintf(("pageFlags == 0\n"));
564 return(TRUE); //nothing to do
565 }
566 ULONG offset = ((ULONG)lpvAddress & 0xFFF);
567 npages = (cbSize >> 12);
568
569 cb = (cbSize & 0xFFF) + offset; // !!! added, some optimization :)
570 if( cb > 0 ) { // changed
571 npages++;
572 }
573 if( cb > 4096 ) { // changed, note '>' sign ( not '>=' ) 4096 is exactly one page
574 npages++;
575 }
576
577 lpvAddress = (LPVOID)((int)lpvAddress & ~0xFFF);
578 cbSize = npages*4096;
579 dprintf(("lpvAddress = %X, cbSize = %d\n", lpvAddress, cbSize));
580
581 rc = OSLibDosSetMem(lpvAddress, cbSize, pageFlags);
582 if(rc) {
583 dprintf(("DosSetMem returned %d\n", rc));
584 return(FALSE);
585 }
586 return(TRUE);
587}
588//******************************************************************************
589//******************************************************************************
590DWORD WIN32API VirtualQuery(LPCVOID lpvAddress,
591 LPMEMORY_BASIC_INFORMATION pmbiBuffer,
592 DWORD cbLength)
593{
594 ULONG cbRangeSize, dAttr;
595 DWORD rc;
596 LPVOID lpBase;
597
598 SetLastError(ERROR_SUCCESS);
599
600 if(pmbiBuffer == NULL || cbLength != sizeof(MEMORY_BASIC_INFORMATION)) // check parameters
601 {
602 dprintf(("WARNING: invalid parameter"));
603 SetLastError(ERROR_INVALID_PARAMETER);
604 return 0; // nothing to return
605 }
606
607 // determine exact page range
608 lpBase = (LPVOID)((ULONG)lpvAddress & 0xFFFFF000);
609 cbRangeSize = -1;
610
611 rc = OSLibDosQueryMem(lpBase, &cbRangeSize, &dAttr);
612 if(rc)
613 {
614 dprintf(("VirtualQuery - OSLibDosQueryMem %x %x returned %d\n",
615 lpBase, cbLength, rc));
616 SetLastError(ERROR_INVALID_PARAMETER);
617 return 0;
618 }
619
620 memset(pmbiBuffer, 0, sizeof(MEMORY_BASIC_INFORMATION));
621
622 pmbiBuffer->BaseAddress = lpBase;
623 //round to next page boundary
624 pmbiBuffer->RegionSize = (cbRangeSize + 0xFFF) & 0xFFFFF000;
625
626 if(dAttr & PAG_READ && !(dAttr & PAG_WRITE))
627 pmbiBuffer->Protect |= PAGE_READONLY;
628
629 if(dAttr & PAG_WRITE)
630 pmbiBuffer->Protect |= PAGE_READWRITE;
631
632 if((dAttr & (PAG_WRITE | PAG_EXECUTE)) == (PAG_WRITE | PAG_EXECUTE))
633 pmbiBuffer->Protect |= PAGE_EXECUTE_READWRITE;
634 else
635 if(dAttr & PAG_EXECUTE)
636 pmbiBuffer->Protect |= PAGE_EXECUTE_READ;
637
638 if(dAttr & PAG_GUARD)
639 pmbiBuffer->Protect |= PAGE_GUARD;
640
641 if(dAttr & PAG_FREE)
642 pmbiBuffer->State = MEM_FREE;
643 else
644 if(dAttr & PAG_COMMIT)
645 pmbiBuffer->State = MEM_COMMIT;
646 else
647 pmbiBuffer->State = MEM_RESERVE;
648
649 //TODO: MEM_MAPPED & MEM_IMAGE (==SEC_IMAGE)
650 if(!(dAttr & PAG_SHARED))
651 pmbiBuffer->Type = MEM_PRIVATE;
652
653 // Pages can be committed but not necessarily accessible!!
654 if (!(dAttr & (PAG_READ | PAG_WRITE | PAG_EXECUTE | PAG_GUARD)))
655 pmbiBuffer->Protect = PAGE_NOACCESS;
656
657 //TODO: This is not correct: AllocationProtect should contain the protection
658 // flags used in the initial call to VirtualAlloc
659 pmbiBuffer->AllocationProtect = pmbiBuffer->Protect;
660 if(dAttr & PAG_BASE) {
661 pmbiBuffer->AllocationBase = lpBase;
662 }
663 else
664 {
665 while(lpBase > 0)
666 {
667 rc = OSLibDosQueryMem(lpBase, &cbRangeSize, &dAttr);
668 if(rc) {
669 dprintf(("VirtualQuery - OSLibDosQueryMem %x %x returned %d\n",
670 lpBase, cbLength, rc));
671 break;
672 }
673 if(dAttr & PAG_BASE) {
674 pmbiBuffer->AllocationBase = lpBase;
675 break;
676 }
677 lpBase = (LPVOID)((ULONG)lpBase - PAGE_SIZE);
678 }
679 }
680 dprintf(("Memory region alloc base 0x%08x", pmbiBuffer->AllocationBase));
681 dprintf(("Memory region alloc protect flags %x", pmbiBuffer->AllocationProtect));
682 dprintf(("Memory region base 0x%08x", pmbiBuffer->BaseAddress));
683 dprintf(("Memory region protect flags %x", pmbiBuffer->Protect));
684 dprintf(("Memory region region size 0x%08x", pmbiBuffer->RegionSize));
685 dprintf(("Memory region state 0x%08x", pmbiBuffer->State));
686 dprintf(("Memory region type 0x%08x", pmbiBuffer->Type));
687 return sizeof(MEMORY_BASIC_INFORMATION);
688}
689//******************************************************************************
690//******************************************************************************
691BOOL WIN32API VirtualLock(LPVOID lpAddress, DWORD dwSize)
692{
693 dprintf(("VirtualLock at %d; %d bytes - stub (TRUE)\n", (int)lpAddress, dwSize));
694 SetLastError(ERROR_SUCCESS);
695 return TRUE;
696}
697
698//******************************************************************************
699BOOL WIN32API VirtualUnlock(LPVOID lpAddress, DWORD dwSize)
700{
701 dprintf(("VirtualUnlock at %d; %d bytes - stub (TRUE)\n", (int)lpAddress, dwSize));
702 SetLastError(ERROR_SUCCESS);
703 return TRUE;
704}
705
706/*****************************************************************************
707 * Name : BOOL VirtualProtectEx
708 * Purpose : The VirtualProtectEx function changes the access protection on
709 * a region of committed pages in the virtual address space of a specified
710 * process. Note that this function differs from VirtualProtect,
711 * which changes the access protection on the calling process only.
712 * Parameters: HANDLE hProcess handle of process
713 * LPVOID lpvAddress address of region of committed pages
714 * DWORD cbSize size of region
715 * DWORD fdwNewProtect desired access protection
716 * PDWORD pfdwOldProtect address of variable to get old protection
717 * Variables :
718 * Result : size of target buffer
719 * Remark :
720 * Status : UNTESTED STUB
721 *
722 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
723 *****************************************************************************/
724
725BOOL WIN32API VirtualProtectEx(HANDLE hProcess,
726 LPVOID lpvAddress,
727 DWORD cbSize,
728 DWORD fdwNewProtect,
729 LPDWORD pfdwOldProtect)
730{
731 // only execute API, if this is the current process !
732 if (GetCurrentProcess() == hProcess)
733 return VirtualProtect(lpvAddress, cbSize, fdwNewProtect, pfdwOldProtect);
734 else
735 {
736 SetLastError(ERROR_ACCESS_DENIED); // deny access to other processes
737 return FALSE;
738 }
739}
740
741
742/*****************************************************************************
743 * Name : DWORD VirtualQueryEx
744 * Purpose : The VirtualQueryEx function provides information about a range
745 * of pages within the virtual address space of a specified process.
746 * Parameters: HANDLE hProcess handle of process
747 * LPCVOID lpvAddress address of region
748 * LPMEMORY_BASIC_INFORMATION pmbiBuffer address of information buffer
749 * DWORD cbLength size of buffer
750 * Variables :
751 * Result : number of bytes returned in buffer
752 * Remark :
753 * Status : UNTESTED STUB
754 *
755 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
756 *****************************************************************************/
757
758DWORD WIN32API VirtualQueryEx(HANDLE hProcess,
759 LPCVOID lpvAddress,
760 LPMEMORY_BASIC_INFORMATION pmbiBuffer,
761 DWORD cbLength)
762{
763 // only execute API, if this is the current process !
764 if (GetCurrentProcess() == hProcess)
765 return VirtualQuery(lpvAddress, pmbiBuffer, cbLength);
766 else
767 {
768 SetLastError(ERROR_ACCESS_DENIED); // deny access to other processes
769 return FALSE;
770 }
771}
772
773//******************************************************************************
774//SvL: Private api
775//******************************************************************************
776LPVOID VirtualAllocShared(DWORD cbSize, DWORD fdwAllocationType,
777 DWORD fdwProtect, LPSTR name)
778{
779 LPVOID Address;
780 ULONG flag = 0, base;
781 DWORD rc;
782
783 dprintf(("VirtualAllocShared: %x %x %x %s", cbSize, fdwAllocationType, fdwProtect, name));
784
785 if (cbSize > 0x7fc00000) /* 2Gb - 4Mb */
786 {
787 dprintf(("VirtualAllocShared: size too large"));
788 SetLastError( ERROR_OUTOFMEMORY );
789 return NULL;
790 }
791
792 if (!(fdwAllocationType & (MEM_COMMIT | MEM_RESERVE)) ||
793 (fdwAllocationType & ~(MEM_COMMIT | MEM_RESERVE)))
794 {
795 dprintf(("VirtualAllocShared: Invalid parameter"));
796 SetLastError( ERROR_INVALID_PARAMETER );
797 return NULL;
798 }
799
800 if(fdwAllocationType & MEM_COMMIT)
801 {
802 dprintf(("VirtualAllocShared: commit\n"));
803 flag = PAG_COMMIT;
804 }
805
806 if(fdwProtect & PAGE_READONLY) flag |= PAG_READ;
807 if(fdwProtect & PAGE_NOACCESS) flag |= PAG_READ; //can't do this in OS/2
808 if(fdwProtect & PAGE_READWRITE) flag |= (PAG_READ | PAG_WRITE);
809 if(fdwProtect & PAGE_WRITECOPY) flag |= (PAG_READ | PAG_WRITE);
810
811 if(fdwProtect & PAGE_EXECUTE_READWRITE) flag |= (PAG_EXECUTE | PAG_WRITE | PAG_READ);
812 if(fdwProtect & PAGE_EXECUTE_READ) flag |= (PAG_EXECUTE | PAG_READ);
813 if(fdwProtect & PAGE_EXECUTE) flag |= PAG_EXECUTE;
814
815 if(fdwProtect & PAGE_GUARD) {
816 dprintf(("ERROR: PAGE_GUARD bit set for VirtualAllocShared -> we don't support this right now!"));
817 flag |= PAG_GUARD;
818 }
819
820 //just do this if other options are used
821 if(!(flag & (PAG_READ | PAG_WRITE | PAG_EXECUTE)) || flag == 0)
822 {
823 dprintf(("VirtualAllocShared: Unknown protection flags, default to read/write"));
824 flag |= PAG_READ | PAG_WRITE;
825 }
826
827 rc = OSLibDosAllocSharedMem(&Address, cbSize, flag, name);
828
829 if(rc)
830 {
831 dprintf(("DosAllocSharedMem returned %d\n", rc));
832 SetLastError( ERROR_OUTOFMEMORY );
833 return(NULL);
834 }
835
836 dprintf(("VirtualAllocShared returned %X\n", Address));
837 return(Address);
838}
Note: See TracBrowser for help on using the repository browser.