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

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

misc fixes

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