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

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

Added new logging feature

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