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

Last change on this file since 3830 was 3483, checked in by sandervl, 25 years ago

added exception stack dump code; GetLocaleInfoA fixes

File size: 24.6 KB
Line 
1/* $Id: virtual.cpp,v 1.30 2000-05-02 20:53:13 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 if(rc == 32803) { //SvL: ERROR_ALIAS
440 dprintf(("KERNEL32:VirtualFree:OsLibSetMem rc = #%d; app tries to decommit aliased memory; ignore", rc));
441 return(TRUE);
442 }
443 dprintf(("KERNEL32:VirtualFree:OsLibSetMem rc = #%d\n", rc));
444 SetLastError(ERROR_INVALID_ADDRESS);
445 return(FALSE);
446 }
447 }
448
449 // release memory
450 if (FreeType & MEM_RELEASE)
451 {
452 rc = OSLibDosFreeMem(lpvAddress); // free the memory block
453 if(rc)
454 {
455 dprintf(("KERNEL32:VirtualFree:OsLibFreeMem rc = #%d\n",
456 rc));
457 SetLastError(ERROR_INVALID_ADDRESS);
458 return(FALSE);
459 }
460 }
461
462 return(TRUE);
463}
464//******************************************************************************
465//LPVOID lpvAddress; /* address of region of committed pages */
466//DWORD cbSize; /* size of the region */
467//DWORD fdwNewProtect; /* desired access protection */
468//PDWORD pfdwOldProtect; /* address of variable to get old protection */
469//TODO: Not 100% complete
470//TODO: SetLastError on failure
471//******************************************************************************
472
473ODINFUNCTION4(BOOL, VirtualProtect, LPVOID, lpvAddress,
474 DWORD, cbSize,
475 DWORD, fdwNewProtect,
476 DWORD*, pfdwOldProtect)
477{
478 DWORD rc;
479 DWORD cb = cbSize;
480 ULONG pageFlags = 0;
481 int npages;
482
483 if(pfdwOldProtect == NULL)
484 return(FALSE);
485
486 rc = OSLibDosQueryMem(lpvAddress, &cb, &pageFlags);
487 if(rc) {
488 dprintf(("DosQueryMem returned %d\n", rc));
489 return(FALSE);
490 }
491 dprintf(("Old memory flags %X\n", pageFlags));
492 *pfdwOldProtect = 0;
493 if(pageFlags & PAG_READ && !(pageFlags & PAG_WRITE))
494 *pfdwOldProtect |= PAGE_READONLY;
495 if(pageFlags & (PAG_WRITE))
496 *pfdwOldProtect |= PAGE_READWRITE;
497
498 if((pageFlags & (PAG_WRITE | PAG_EXECUTE)) == (PAG_WRITE | PAG_EXECUTE))
499 *pfdwOldProtect |= PAGE_EXECUTE_READWRITE;
500 else
501 if(pageFlags & PAG_EXECUTE)
502 *pfdwOldProtect |= PAGE_EXECUTE_READ;
503
504 if(pageFlags & PAG_GUARD)
505 *pfdwOldProtect |= PAGE_GUARD;
506 pageFlags = 0;
507
508 if(fdwNewProtect & PAGE_READONLY) pageFlags |= PAG_READ;
509 if(fdwNewProtect & PAGE_READWRITE) pageFlags |= (PAG_READ | PAG_WRITE);
510 if(fdwNewProtect & PAGE_WRITECOPY) pageFlags |= (PAG_READ | PAG_WRITE);
511 if(fdwNewProtect & PAGE_EXECUTE_READ) pageFlags |= (PAG_EXECUTE | PAG_READ);
512 if(fdwNewProtect & PAGE_EXECUTE_READWRITE)
513 pageFlags |= (PAG_EXECUTE | PAG_WRITE | PAG_READ);
514 if(fdwNewProtect & PAGE_EXECUTE_WRITECOPY)
515 pageFlags |= (PAG_EXECUTE | PAG_WRITE | PAG_READ);
516 if(fdwNewProtect & PAGE_GUARD) pageFlags |= PAG_GUARD;
517//Not supported in OS/2??
518// if(fdwNewProtect & PAGE_NOACCESS)
519
520 dprintf(("New memory flags %X\n", pageFlags));
521 if(pageFlags == 0) {
522 dprintf(("pageFlags == 0\n"));
523 return(TRUE); //nothing to do
524 }
525 ULONG offset = ((ULONG)lpvAddress & 0xFFF);
526 npages = (cbSize >> 12);
527
528 cb = (cbSize & 0xFFF) + offset; // !!! added, some optimization :)
529 if( cb > 0 ) { // changed
530 npages++;
531 }
532 if( cb > 4096 ) { // changed, note '>' sign ( not '>=' ) 4096 is exactly one page
533 npages++;
534 }
535
536 lpvAddress = (LPVOID)((int)lpvAddress & ~0xFFF);
537 cbSize = npages*4096;
538 dprintf(("lpvAddress = %X, cbSize = %d\n", lpvAddress, cbSize));
539
540 rc = OSLibDosSetMem(lpvAddress, cbSize, pageFlags);
541 if(rc) {
542 dprintf(("DosSetMem returned %d\n", rc));
543 return(FALSE);
544 }
545 return(TRUE);
546}
547//******************************************************************************
548//******************************************************************************
549ODINFUNCTION3(DWORD, VirtualQuery, LPCVOID, lpvAddress,
550 LPMEMORY_BASIC_INFORMATION, pmbiBuffer,
551 DWORD, cbLength)
552{
553 ULONG cbRangeSize,
554 dAttr;
555 DWORD rc;
556 LPVOID lpBase;
557
558 if(pmbiBuffer == NULL || cbLength != sizeof(MEMORY_BASIC_INFORMATION)) // check parameters
559 {
560 SetLastError(ERROR_INVALID_PARAMETER);
561 return 0; // nothing to return
562 }
563 SetLastError(ERROR_SUCCESS);
564
565 // determine exact page range
566 lpBase = (LPVOID)((ULONG)lpvAddress & 0xFFFFF000);
567 cbRangeSize = -1;
568
569 rc = OSLibDosQueryMem(lpBase,
570 &cbRangeSize,
571 &dAttr);
572 if(rc)
573 {
574 dprintf(("VirtualQuery - OSLibDosQueryMem %x %x returned %d\n",
575 lpBase, cbLength, rc));
576 SetLastError(ERROR_INVALID_PARAMETER);
577 return 0;
578 }
579
580 memset(pmbiBuffer,
581 0,
582 sizeof(MEMORY_BASIC_INFORMATION));
583
584 pmbiBuffer->BaseAddress = lpBase;
585 pmbiBuffer->RegionSize = cbRangeSize;
586
587 if(dAttr & PAG_READ && !(dAttr & PAG_WRITE))
588 pmbiBuffer->Protect |= PAGE_READONLY;
589
590 if(dAttr & PAG_WRITE)
591 pmbiBuffer->Protect |= PAGE_READWRITE;
592
593 if((dAttr & (PAG_WRITE | PAG_EXECUTE)) == (PAG_WRITE | PAG_EXECUTE))
594 pmbiBuffer->Protect |= PAGE_EXECUTE_READWRITE;
595 else
596 if(dAttr & PAG_EXECUTE)
597 pmbiBuffer->Protect |= PAGE_EXECUTE_READ;
598
599 if(dAttr & PAG_GUARD)
600 pmbiBuffer->Protect |= PAGE_GUARD;
601
602 if(dAttr & PAG_FREE)
603 pmbiBuffer->State = MEM_FREE;
604 else
605 if(dAttr & PAG_COMMIT)
606 pmbiBuffer->State = MEM_COMMIT;
607 else
608 pmbiBuffer->State = MEM_RESERVE;
609
610 if(!(dAttr & PAG_SHARED))
611 pmbiBuffer->Type = MEM_PRIVATE;
612
613 //TODO: This is not correct: AllocationProtect should contain the protection
614 // flags used in the initial call to VirtualAlloc
615 pmbiBuffer->AllocationProtect = pmbiBuffer->Protect;
616 if(dAttr & PAG_BASE) {
617 pmbiBuffer->AllocationBase = lpBase;
618 }
619 else
620 {
621 while(lpBase > 0)
622 {
623 rc = OSLibDosQueryMem(lpBase, &cbRangeSize, &dAttr);
624 if(rc) {
625 dprintf(("VirtualQuery - OSLibDosQueryMem %x %x returned %d\n",
626 lpBase, cbLength, rc));
627 break;
628 }
629 if(dAttr & PAG_BASE) {
630 pmbiBuffer->AllocationBase = lpBase;
631 break;
632 }
633 lpBase = (LPVOID)((ULONG)lpBase - PAGE_SIZE);
634 }
635 }
636 return sizeof(MEMORY_BASIC_INFORMATION);
637}
638//******************************************************************************
639//******************************************************************************
640ODINFUNCTION2(BOOL, VirtualLock, LPVOID, lpAddress,
641 DWORD, dwSize)
642{
643 dprintf(("VirtualLock at %d; %d bytes - stub (TRUE)\n", (int)lpAddress, dwSize));
644 return TRUE;
645}
646
647//******************************************************************************
648ODINFUNCTION2(BOOL, VirtualUnlock, LPVOID, lpAddress,
649 DWORD, dwSize)
650{
651 dprintf(("VirtualUnlock at %d; %d bytes - stub (TRUE)\n", (int)lpAddress, dwSize));
652 return TRUE;
653}
654
655/*****************************************************************************
656 * Name : BOOL VirtualProtectEx
657 * Purpose : The VirtualProtectEx function changes the access protection on
658 * a region of committed pages in the virtual address space of a specified
659 * process. Note that this function differs from VirtualProtect,
660 * which changes the access protection on the calling process only.
661 * Parameters: HANDLE hProcess handle of process
662 * LPVOID lpvAddress address of region of committed pages
663 * DWORD cbSize size of region
664 * DWORD fdwNewProtect desired access protection
665 * PDWORD pfdwOldProtect address of variable to get old protection
666 * Variables :
667 * Result : size of target buffer
668 * Remark :
669 * Status : UNTESTED STUB
670 *
671 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
672 *****************************************************************************/
673
674ODINFUNCTION5(BOOL, VirtualProtectEx, HANDLE, hProcess,
675 LPVOID, lpvAddress,
676 DWORD, cbSize,
677 DWORD, fdwNewProtect,
678 LPDWORD, pfdwOldProtect)
679{
680 // only execute API, if this is the current process !
681 if (GetCurrentProcess() == hProcess)
682 return VirtualProtect(lpvAddress, cbSize, fdwNewProtect, pfdwOldProtect);
683 else
684 {
685 SetLastError(ERROR_ACCESS_DENIED); // deny access to other processes
686 return FALSE;
687 }
688}
689
690
691/*****************************************************************************
692 * Name : DWORD VirtualQueryEx
693 * Purpose : The VirtualQueryEx function provides information about a range
694 * of pages within the virtual address space of a specified process.
695 * Parameters: HANDLE hProcess handle of process
696 * LPCVOID lpvAddress address of region
697 * LPMEMORY_BASIC_INFORMATION pmbiBuffer address of information buffer
698 * DWORD cbLength size of buffer
699 * Variables :
700 * Result : number of bytes returned in buffer
701 * Remark :
702 * Status : UNTESTED STUB
703 *
704 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
705 *****************************************************************************/
706
707ODINFUNCTION4(DWORD, VirtualQueryEx, HANDLE, hProcess,
708 LPCVOID, lpvAddress,
709 LPMEMORY_BASIC_INFORMATION, pmbiBuffer,
710 DWORD, cbLength)
711{
712 // only execute API, if this is the current process !
713 if (GetCurrentProcess() == hProcess)
714 return VirtualQuery(lpvAddress, pmbiBuffer, cbLength);
715 else
716 {
717 SetLastError(ERROR_ACCESS_DENIED); // deny access to other processes
718 return FALSE;
719 }
720}
721
722//******************************************************************************
723//SvL: Private api
724//******************************************************************************
725LPVOID VirtualAllocShared(DWORD cbSize, DWORD fdwAllocationType,
726 DWORD fdwProtect, LPSTR name)
727{
728 LPVOID Address;
729 ULONG flag = 0, base;
730 DWORD rc;
731
732 dprintf(("VirtualAllocShared: %x %x %x %s", cbSize, fdwAllocationType, fdwProtect, name));
733
734 if (cbSize > 0x7fc00000) /* 2Gb - 4Mb */
735 {
736 dprintf(("VirtualAllocShared: size too large"));
737 SetLastError( ERROR_OUTOFMEMORY );
738 return NULL;
739 }
740
741 if (!(fdwAllocationType & (MEM_COMMIT | MEM_RESERVE)) ||
742 (fdwAllocationType & ~(MEM_COMMIT | MEM_RESERVE)))
743 {
744 dprintf(("VirtualAllocShared: Invalid parameter"));
745 SetLastError( ERROR_INVALID_PARAMETER );
746 return NULL;
747 }
748
749 if(fdwAllocationType & MEM_COMMIT)
750 {
751 dprintf(("VirtualAllocShared: commit\n"));
752 flag = PAG_COMMIT;
753 }
754
755 if(fdwProtect & PAGE_READONLY) flag |= PAG_READ;
756 if(fdwProtect & PAGE_NOACCESS) flag |= PAG_READ; //can't do this in OS/2
757 if(fdwProtect & PAGE_READWRITE) flag |= (PAG_READ | PAG_WRITE);
758 if(fdwProtect & PAGE_WRITECOPY) flag |= (PAG_READ | PAG_WRITE);
759
760 if(fdwProtect & PAGE_EXECUTE_READWRITE) flag |= (PAG_EXECUTE | PAG_WRITE | PAG_READ);
761 if(fdwProtect & PAGE_EXECUTE_READ) flag |= (PAG_EXECUTE | PAG_READ);
762 if(fdwProtect & PAGE_EXECUTE) flag |= PAG_EXECUTE;
763
764 if(fdwProtect & PAGE_GUARD) {
765 dprintf(("ERROR: PAGE_GUARD bit set for VirtualAllocShared -> we don't support this right now!"));
766 flag |= PAG_GUARD;
767 }
768
769 //just do this if other options are used
770 if(!(flag & (PAG_READ | PAG_WRITE | PAG_EXECUTE)) || flag == 0)
771 {
772 dprintf(("VirtualAllocShared: Unknown protection flags, default to read/write"));
773 flag |= PAG_READ | PAG_WRITE;
774 }
775
776 rc = OSLibDosAllocSharedMem(&Address, cbSize, flag, name);
777
778 if(rc)
779 {
780 dprintf(("DosAllocSharedMem returned %d\n", rc));
781 SetLastError( ERROR_OUTOFMEMORY );
782 return(NULL);
783 }
784
785 dprintf(("VirtualAllocShared returned %X\n", Address));
786 return(Address);
787}
Note: See TracBrowser for help on using the repository browser.