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

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

VirtualAlloc change for PAGE_NOACCESS

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