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

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

openfile, virtualquery + import name fixes

File size: 24.4 KB
Line 
1/* $Id: virtual.cpp,v 1.29 2000-03-28 17:11:50 sandervl Exp $ */
2
3/*
4 * Win32 virtual memory functions
5 *
6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1998 Knut St. Osmundsen
8 * Copyright 1998 Peter FitzSimmons
9 *
10 * Parts (VIRTUAL_MapFileA/W) based on Wine code (memory\virtual.c):
11 *
12 * Copyright 1997 Alexandre Julliard
13 *
14 * Project Odin Software License can be found in LICENSE.TXT
15 *
16 */
17
18#include <odin.h>
19#include <odinwrap.h>
20
21#include <os2win.h>
22#include <stdlib.h>
23#include <string.h>
24#include <win\virtual.h>
25#include <heapstring.h>
26#include <handlemanager.h>
27#include "mmap.h"
28#include "oslibdos.h"
29
30#define DBG_LOCALLOG DBG_virtual
31#include "dbglocal.h"
32
33ODINDEBUGCHANNEL(KERNEL32-VIRTUAL)
34
35#define PAGE_SHIFT 12
36
37/***********************************************************************
38 * CreateFileMapping32A (KERNEL32.46)
39 * Creates a named or unnamed file-mapping object for the specified file
40 *
41 * RETURNS
42 * Handle: Success
43 * 0: Mapping object does not exist
44 * NULL: Failure
45 */
46HANDLE WINAPI CreateFileMappingA(
47 HFILE hFile, /* [in] Handle of file to map */
48 SECURITY_ATTRIBUTES *sa, /* [in] Optional security attributes*/
49 DWORD protect, /* [in] Protection for mapping object */
50 DWORD size_high, /* [in] High-order 32 bits of object size */
51 DWORD size_low, /* [in] Low-order 32 bits of object size */
52 LPCSTR name /* [in] Name of file-mapping object */ )
53{
54 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 != sizeof(MEMORY_BASIC_INFORMATION)) // check parameters
556 {
557 SetLastError(ERROR_INVALID_PARAMETER);
558 return 0; // nothing to return
559 }
560 SetLastError(ERROR_SUCCESS);
561
562 // determine exact page range
563 lpBase = (LPVOID)((ULONG)lpvAddress & 0xFFFFF000);
564 cbRangeSize = -1;
565
566 rc = OSLibDosQueryMem(lpBase,
567 &cbRangeSize,
568 &dAttr);
569 if(rc)
570 {
571 dprintf(("VirtualQuery - OSLibDosQueryMem %x %x returned %d\n",
572 lpBase, cbLength, rc));
573 SetLastError(ERROR_INVALID_PARAMETER);
574 return 0;
575 }
576
577 memset(pmbiBuffer,
578 0,
579 sizeof(MEMORY_BASIC_INFORMATION));
580
581 pmbiBuffer->BaseAddress = lpBase;
582 pmbiBuffer->RegionSize = cbRangeSize;
583
584 if(dAttr & PAG_READ && !(dAttr & PAG_WRITE))
585 pmbiBuffer->Protect |= PAGE_READONLY;
586
587 if(dAttr & PAG_WRITE)
588 pmbiBuffer->Protect |= PAGE_READWRITE;
589
590 if((dAttr & (PAG_WRITE | PAG_EXECUTE)) == (PAG_WRITE | PAG_EXECUTE))
591 pmbiBuffer->Protect |= PAGE_EXECUTE_READWRITE;
592 else
593 if(dAttr & PAG_EXECUTE)
594 pmbiBuffer->Protect |= PAGE_EXECUTE_READ;
595
596 if(dAttr & PAG_GUARD)
597 pmbiBuffer->Protect |= PAGE_GUARD;
598
599 if(dAttr & PAG_FREE)
600 pmbiBuffer->State = MEM_FREE;
601 else
602 if(dAttr & PAG_COMMIT)
603 pmbiBuffer->State = MEM_COMMIT;
604 else
605 pmbiBuffer->State = MEM_RESERVE;
606
607 if(!(dAttr & PAG_SHARED))
608 pmbiBuffer->Type = MEM_PRIVATE;
609
610 //TODO: This is not correct: AllocationProtect should contain the protection
611 // flags used in the initial call to VirtualAlloc
612 pmbiBuffer->AllocationProtect = pmbiBuffer->Protect;
613 if(dAttr & PAG_BASE) {
614 pmbiBuffer->AllocationBase = lpBase;
615 }
616 else
617 {
618 while(lpBase > 0)
619 {
620 rc = OSLibDosQueryMem(lpBase, &cbRangeSize, &dAttr);
621 if(rc) {
622 dprintf(("VirtualQuery - OSLibDosQueryMem %x %x returned %d\n",
623 lpBase, cbLength, rc));
624 break;
625 }
626 if(dAttr & PAG_BASE) {
627 pmbiBuffer->AllocationBase = lpBase;
628 break;
629 }
630 lpBase = (LPVOID)((ULONG)lpBase - PAGE_SIZE);
631 }
632 }
633 return sizeof(MEMORY_BASIC_INFORMATION);
634}
635//******************************************************************************
636//******************************************************************************
637ODINFUNCTION2(BOOL, VirtualLock, LPVOID, lpAddress,
638 DWORD, dwSize)
639{
640 dprintf(("VirtualLock at %d; %d bytes - stub (TRUE)\n", (int)lpAddress, dwSize));
641 return TRUE;
642}
643
644//******************************************************************************
645ODINFUNCTION2(BOOL, VirtualUnlock, LPVOID, lpAddress,
646 DWORD, dwSize)
647{
648 dprintf(("VirtualUnlock at %d; %d bytes - stub (TRUE)\n", (int)lpAddress, dwSize));
649 return TRUE;
650}
651
652/*****************************************************************************
653 * Name : BOOL VirtualProtectEx
654 * Purpose : The VirtualProtectEx function changes the access protection on
655 * a region of committed pages in the virtual address space of a specified
656 * process. Note that this function differs from VirtualProtect,
657 * which changes the access protection on the calling process only.
658 * Parameters: HANDLE hProcess handle of process
659 * LPVOID lpvAddress address of region of committed pages
660 * DWORD cbSize size of region
661 * DWORD fdwNewProtect desired access protection
662 * PDWORD pfdwOldProtect address of variable to get old protection
663 * Variables :
664 * Result : size of target buffer
665 * Remark :
666 * Status : UNTESTED STUB
667 *
668 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
669 *****************************************************************************/
670
671ODINFUNCTION5(BOOL, VirtualProtectEx, HANDLE, hProcess,
672 LPVOID, lpvAddress,
673 DWORD, cbSize,
674 DWORD, fdwNewProtect,
675 LPDWORD, pfdwOldProtect)
676{
677 // only execute API, if this is the current process !
678 if (GetCurrentProcess() == hProcess)
679 return VirtualProtect(lpvAddress, cbSize, fdwNewProtect, pfdwOldProtect);
680 else
681 {
682 SetLastError(ERROR_ACCESS_DENIED); // deny access to other processes
683 return FALSE;
684 }
685}
686
687
688/*****************************************************************************
689 * Name : DWORD VirtualQueryEx
690 * Purpose : The VirtualQueryEx function provides information about a range
691 * of pages within the virtual address space of a specified process.
692 * Parameters: HANDLE hProcess handle of process
693 * LPCVOID lpvAddress address of region
694 * LPMEMORY_BASIC_INFORMATION pmbiBuffer address of information buffer
695 * DWORD cbLength size of buffer
696 * Variables :
697 * Result : number of bytes returned in buffer
698 * Remark :
699 * Status : UNTESTED STUB
700 *
701 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
702 *****************************************************************************/
703
704ODINFUNCTION4(DWORD, VirtualQueryEx, HANDLE, hProcess,
705 LPCVOID, lpvAddress,
706 LPMEMORY_BASIC_INFORMATION, pmbiBuffer,
707 DWORD, cbLength)
708{
709 // only execute API, if this is the current process !
710 if (GetCurrentProcess() == hProcess)
711 return VirtualQuery(lpvAddress, pmbiBuffer, cbLength);
712 else
713 {
714 SetLastError(ERROR_ACCESS_DENIED); // deny access to other processes
715 return FALSE;
716 }
717}
718
719//******************************************************************************
720//SvL: Private api
721//******************************************************************************
722LPVOID VirtualAllocShared(DWORD cbSize, DWORD fdwAllocationType,
723 DWORD fdwProtect, LPSTR name)
724{
725 LPVOID Address;
726 ULONG flag = 0, base;
727 DWORD rc;
728
729 dprintf(("VirtualAllocShared: %x %x %x %s", cbSize, fdwAllocationType, fdwProtect, name));
730
731 if (cbSize > 0x7fc00000) /* 2Gb - 4Mb */
732 {
733 dprintf(("VirtualAllocShared: size too large"));
734 SetLastError( ERROR_OUTOFMEMORY );
735 return NULL;
736 }
737
738 if (!(fdwAllocationType & (MEM_COMMIT | MEM_RESERVE)) ||
739 (fdwAllocationType & ~(MEM_COMMIT | MEM_RESERVE)))
740 {
741 dprintf(("VirtualAllocShared: Invalid parameter"));
742 SetLastError( ERROR_INVALID_PARAMETER );
743 return NULL;
744 }
745
746 if(fdwAllocationType & MEM_COMMIT)
747 {
748 dprintf(("VirtualAllocShared: commit\n"));
749 flag = PAG_COMMIT;
750 }
751
752 if(fdwProtect & PAGE_READONLY) flag |= PAG_READ;
753 if(fdwProtect & PAGE_NOACCESS) flag |= PAG_READ; //can't do this in OS/2
754 if(fdwProtect & PAGE_READWRITE) flag |= (PAG_READ | PAG_WRITE);
755 if(fdwProtect & PAGE_WRITECOPY) flag |= (PAG_READ | PAG_WRITE);
756
757 if(fdwProtect & PAGE_EXECUTE_READWRITE) flag |= (PAG_EXECUTE | PAG_WRITE | PAG_READ);
758 if(fdwProtect & PAGE_EXECUTE_READ) flag |= (PAG_EXECUTE | PAG_READ);
759 if(fdwProtect & PAGE_EXECUTE) flag |= PAG_EXECUTE;
760
761 if(fdwProtect & PAGE_GUARD) {
762 dprintf(("ERROR: PAGE_GUARD bit set for VirtualAllocShared -> we don't support this right now!"));
763 flag |= PAG_GUARD;
764 }
765
766 //just do this if other options are used
767 if(!(flag & (PAG_READ | PAG_WRITE | PAG_EXECUTE)) || flag == 0)
768 {
769 dprintf(("VirtualAllocShared: Unknown protection flags, default to read/write"));
770 flag |= PAG_READ | PAG_WRITE;
771 }
772
773 rc = OSLibDosAllocSharedMem(&Address, cbSize, flag, name);
774
775 if(rc)
776 {
777 dprintf(("DosAllocSharedMem returned %d\n", rc));
778 SetLastError( ERROR_OUTOFMEMORY );
779 return(NULL);
780 }
781
782 dprintf(("VirtualAllocShared returned %X\n", Address));
783 return(Address);
784}
Note: See TracBrowser for help on using the repository browser.