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

Last change on this file since 2525 was 2525, checked in by sandervl, 26 years ago

Added workaround for OS/2 DosSetMem bug in VirtualAlloc

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