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

Last change on this file since 1301 was 1301, checked in by phaller, 26 years ago

Fix: VirtualQuery was broken

File size: 20.7 KB
Line 
1/* $Id: virtual.cpp,v 1.18 1999-10-14 20:55:39 phaller 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_READWRITE) flag |= (PAG_READ | PAG_WRITE);
290 if(fdwProtect & PAGE_WRITECOPY) flag |= (PAG_READ | PAG_WRITE);
291
292 if(fdwProtect & PAGE_EXECUTE_READWRITE) flag |= (PAG_EXECUTE | PAG_WRITE | PAG_READ);
293 if(fdwProtect & PAGE_EXECUTE_READ) flag |= (PAG_EXECUTE | PAG_READ);
294 if(fdwProtect & PAGE_EXECUTE) flag |= PAG_EXECUTE;
295
296 if(fdwProtect & PAGE_GUARD) flag |= PAG_GUARD;
297
298 //just do this if other options are used
299 if(!(flag & (PAG_READ | PAG_WRITE | PAG_EXECUTE)) || flag == 0)
300 {
301 dprintf(("VirtualAlloc: Unknown protection flags, default to read/write"));
302 flag |= PAG_READ | PAG_WRITE;
303 }
304
305 // commit memory
306 if(fdwAllocationType & MEM_COMMIT)
307 {
308 Address = lpvAddress;
309
310 rc = OSLibDosSetMem(lpvAddress, cbSize, flag);
311
312 //might try to commit larger part with same base address
313 if(rc == OSLIB_ERROR_ACCESS_DENIED && cbSize > 4096 )
314 { //knut: AND more than one page
315 char *newbase = (char *)lpvAddress + ((cbSize-1) & 0xFFFFF000); //knut: lets not start after the last page!
316 ULONG size, os2flags;
317
318 while(newbase >= (char *)lpvAddress)
319 { //knut: should check first page to!!
320 size = 4096;
321 os2flags = 0;
322 rc = OSLibDosQueryMem(newbase, &size, &os2flags);
323 if(rc)
324 break;
325
326 if(os2flags & PAG_COMMIT)
327 {
328 newbase += 4096;
329 break;
330 }
331 newbase -= 4096;
332 }
333
334 if(rc == 0)
335 {
336 //In case it wants to commit bytes that fall into the last
337 //page of the previous commit command
338 if(cbSize > ((int)newbase - (int)lpvAddress))
339 rc = OSLibDosSetMem(newbase, cbSize - ((int)newbase - (int)lpvAddress), flag);
340 }
341 else return(NULL);
342
343 }
344 else
345 {
346 if(rc == OSLIB_ERROR_INVALID_ADDRESS) {
347 rc = OSLibDosAllocMem(&Address, cbSize, flag );
348 }
349 else
350 if(rc) dprintf(("Unexpected DosSetMem error %x", rc));
351 }
352 }
353 else
354 {
355 rc = OSLibDosAllocMem(&Address, cbSize, flag);
356 }
357
358 if(rc)
359 {
360 dprintf(("DosSetMem returned %d\n", rc));
361 SetLastError( ERROR_OUTOFMEMORY );
362 return(NULL);
363 }
364
365 dprintf(("VirtualAlloc returned %X\n", Address));
366 return(Address);
367}
368//******************************************************************************
369//******************************************************************************
370ODINFUNCTION3(BOOL, VirtualFree, LPVOID, lpvAddress,
371 DWORD, cbSize,
372 DWORD, FreeType)
373{
374 DWORD rc;
375
376 // verify parameters
377 if ( (FreeType & MEM_RELEASE) && (cbSize != 0) )
378 {
379 SetLastError(ERROR_INVALID_PARAMETER);
380 return(FALSE);
381 }
382
383 if ( (FreeType & MEM_DECOMMIT) &&
384 (FreeType & MEM_RELEASE) )
385 {
386 SetLastError(ERROR_INVALID_PARAMETER);
387 return(FALSE);
388 }
389
390 // decommit memory
391 if (FreeType & MEM_DECOMMIT)
392 {
393 // decommit memory block
394 rc = OSLibDosSetMem(lpvAddress, cbSize, PAG_DECOMMIT);
395 if(rc)
396 {
397 dprintf(("KERNEL32:VirtualFree:OsLibSetMem rc = #%d\n",
398 rc));
399 SetLastError(ERROR_INVALID_ADDRESS);
400 return(FALSE);
401 }
402 }
403
404 // release memory
405 if (FreeType & MEM_RELEASE)
406 {
407 rc = OSLibDosFreeMem(lpvAddress); // free the memory block
408 if(rc)
409 {
410 dprintf(("KERNEL32:VirtualFree:OsLibFreeMem rc = #%d\n",
411 rc));
412 SetLastError(ERROR_INVALID_ADDRESS);
413 return(FALSE);
414 }
415 }
416
417 return(TRUE);
418}
419//******************************************************************************
420//LPVOID lpvAddress; /* address of region of committed pages */
421//DWORD cbSize; /* size of the region */
422//DWORD fdwNewProtect; /* desired access protection */
423//PDWORD pfdwOldProtect; /* address of variable to get old protection */
424//TODO: Not 100% complete
425//TODO: SetLastError on failure
426//******************************************************************************
427
428ODINFUNCTION4(BOOL, VirtualProtect, LPVOID, lpvAddress,
429 DWORD, cbSize,
430 DWORD, fdwNewProtect,
431 DWORD*, pfdwOldProtect)
432{
433 DWORD rc;
434 ULONG pageFlags = 0;
435 int npages;
436
437 if(pfdwOldProtect == NULL)
438 return(FALSE);
439
440 rc = OSLibDosQueryMem(lpvAddress, &cbSize, &pageFlags);
441 if(rc) {
442 dprintf(("DosQueryMem returned %d\n", rc));
443 return(FALSE);
444 }
445 dprintf(("Old memory flags %X\n", pageFlags));
446 *pfdwOldProtect = 0;
447 if(pageFlags & PAG_READ && !(pageFlags & PAG_WRITE))
448 *pfdwOldProtect |= PAGE_READONLY;
449 if(pageFlags & (PAG_WRITE))
450 *pfdwOldProtect |= PAGE_READWRITE;
451
452 if((pageFlags & (PAG_WRITE | PAG_EXECUTE)) == (PAG_WRITE | PAG_EXECUTE))
453 *pfdwOldProtect |= PAGE_EXECUTE_READWRITE;
454 else
455 if(pageFlags & PAG_EXECUTE)
456 *pfdwOldProtect |= PAGE_EXECUTE_READ;
457
458 if(pageFlags & PAG_GUARD)
459 *pfdwOldProtect |= PAGE_GUARD;
460 pageFlags = 0;
461
462 if(fdwNewProtect & PAGE_READONLY) pageFlags |= PAG_READ;
463 if(fdwNewProtect & PAGE_READWRITE) pageFlags |= (PAG_READ | PAG_WRITE);
464 if(fdwNewProtect & PAGE_WRITECOPY) pageFlags |= (PAG_READ | PAG_WRITE);
465 if(fdwNewProtect & PAGE_EXECUTE_READ) pageFlags |= (PAG_EXECUTE | PAG_READ);
466 if(fdwNewProtect & PAGE_EXECUTE_READWRITE)
467 pageFlags |= (PAG_EXECUTE | PAG_WRITE | PAG_READ);
468 if(fdwNewProtect & PAGE_EXECUTE_WRITECOPY)
469 pageFlags |= (PAG_EXECUTE | PAG_WRITE | PAG_READ);
470 if(fdwNewProtect & PAGE_GUARD) pageFlags |= PAG_GUARD;
471//Not supported in OS/2??
472// if(fdwNewProtect & PAGE_NOACCESS)
473
474 dprintf(("New memory flags %X\n", pageFlags));
475 if(pageFlags == 0) {
476 dprintf(("pageFlags == 0\n"));
477 return(TRUE); //nothing to do
478 }
479 ULONG offset = ((ULONG)lpvAddress & 0xFFF);
480 npages = (cbSize >> 12);
481 if(cbSize & 0xFFF + offset) {
482 npages++;
483 }
484
485 lpvAddress = (LPVOID)((int)lpvAddress & ~0xFFF);
486 cbSize = npages*4096;
487 dprintf(("lpvAddress = %X, cbSize = %d\n", lpvAddress, cbSize));
488
489 rc = OSLibDosSetMem(lpvAddress, cbSize, pageFlags);
490 if(rc) {
491 dprintf(("DosSetMem returned %d\n", rc));
492 return(FALSE);
493 }
494 return(TRUE);
495}
496//******************************************************************************
497//******************************************************************************
498ODINFUNCTION3(DWORD, VirtualQuery, LPCVOID, lpvAddress,
499 LPMEMORY_BASIC_INFORMATION, pmbiBuffer,
500 DWORD, cbLength)
501{
502 ULONG cbRangeSize,
503 dAttr;
504 DWORD rc;
505 LPVOID lpBase;
506
507 if(pmbiBuffer == NULL || cbLength == 0) // check parameters
508 {
509 return 0; // nothing to return
510 }
511
512 // determine exact page range
513 lpBase = (LPVOID)((ULONG)lpvAddress & 0xFFFFF000);
514 cbRangeSize = cbLength & ~0x00000FFF; // assuming intel page sizes :)
515 if(cbLength & 0x00000FFF)
516 cbRangeSize += PAGE_SIZE;
517
518 rc = OSLibDosQueryMem(lpBase,
519 &cbRangeSize,
520 &dAttr);
521 if(rc)
522 {
523 dprintf(("VirtualQuery - OSLibDosQueryMem %x %x returned %d\n",
524 lpBase,
525 cbLength,
526 rc));
527 return 0;
528 }
529
530 memset(pmbiBuffer,
531 0,
532 sizeof(MEMORY_BASIC_INFORMATION));
533
534 pmbiBuffer->BaseAddress = lpBase;
535 pmbiBuffer->RegionSize = cbRangeSize;
536
537 if(dAttr & PAG_READ && !(dAttr & PAG_WRITE))
538 pmbiBuffer->Protect |= PAGE_READONLY;
539
540 if(dAttr & PAG_WRITE)
541 pmbiBuffer->Protect |= PAGE_READWRITE;
542
543 if((dAttr & (PAG_WRITE | PAG_EXECUTE)) == (PAG_WRITE | PAG_EXECUTE))
544 pmbiBuffer->Protect |= PAGE_EXECUTE_READWRITE;
545 else
546 if(dAttr & PAG_EXECUTE)
547 pmbiBuffer->Protect |= PAGE_EXECUTE_READ;
548
549 if(dAttr & PAG_GUARD)
550 pmbiBuffer->Protect |= PAGE_GUARD;
551
552 if(dAttr & PAG_FREE)
553 pmbiBuffer->State = MEM_FREE;
554 else
555 if(dAttr & PAG_COMMIT)
556 pmbiBuffer->State = MEM_COMMIT;
557 else
558 pmbiBuffer->State = MEM_RESERVE;
559
560 if(!(dAttr & PAG_SHARED))
561 pmbiBuffer->Type = MEM_PRIVATE;
562
563 //TODO: This is not correct: AllocationProtect should contain the protection
564 // flags used in the initial call to VirtualAlloc
565 pmbiBuffer->AllocationProtect = pmbiBuffer->Protect;
566 if(dAttr & PAG_BASE)
567 pmbiBuffer->AllocationBase = lpBase;
568 else
569 {
570 while(lpBase > 0)
571 {
572 rc = OSLibDosQueryMem(lpBase, &cbRangeSize, &dAttr);
573 if(rc)
574 {
575 dprintf(("VirtualQuery - OSLibDosQueryMem %x %x returned %d\n",
576 lpBase,
577 cbLength,
578 rc));
579 break;
580 }
581 if(dAttr & PAG_BASE)
582 {
583 pmbiBuffer->AllocationBase = lpBase;
584 break;
585 }
586 lpBase = (LPVOID) ((LPBYTE)lpBase - PAGE_SIZE);
587 }
588 }
589 return sizeof(MEMORY_BASIC_INFORMATION);
590}
591//******************************************************************************
592//******************************************************************************
593ODINFUNCTION2(BOOL, VirtualLock, LPVOID, lpAddress,
594 DWORD, dwSize)
595{
596 dprintf(("VirtualLock at %d; %d bytes - stub (TRUE)\n", (int)lpAddress, dwSize));
597 return TRUE;
598}
599
600//******************************************************************************
601ODINFUNCTION2(BOOL, VirtualUnlock, LPVOID, lpAddress,
602 DWORD, dwSize)
603{
604 dprintf(("VirtualUnlock at %d; %d bytes - stub (TRUE)\n", (int)lpAddress, dwSize));
605 return TRUE;
606}
607
608/*****************************************************************************
609 * Name : BOOL VirtualProtectEx
610 * Purpose : The VirtualProtectEx function changes the access protection on
611 * a region of committed pages in the virtual address space of a specified
612 * process. Note that this function differs from VirtualProtect,
613 * which changes the access protection on the calling process only.
614 * Parameters: HANDLE hProcess handle of process
615 * LPVOID lpvAddress address of region of committed pages
616 * DWORD cbSize size of region
617 * DWORD fdwNewProtect desired access protection
618 * PDWORD pfdwOldProtect address of variable to get old protection
619 * Variables :
620 * Result : size of target buffer
621 * Remark :
622 * Status : UNTESTED STUB
623 *
624 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
625 *****************************************************************************/
626
627ODINFUNCTION5(BOOL, VirtualProtectEx, HANDLE, hProcess,
628 LPVOID, lpvAddress,
629 DWORD, cbSize,
630 DWORD, fdwNewProtect,
631 LPDWORD, pfdwOldProtect)
632{
633 // only execute API, if this is the current process !
634 if (GetCurrentProcess() == hProcess)
635 return VirtualProtect(lpvAddress, cbSize, fdwNewProtect, pfdwOldProtect);
636 else
637 {
638 SetLastError(ERROR_ACCESS_DENIED); // deny access to other processes
639 return FALSE;
640 }
641}
642
643
644/*****************************************************************************
645 * Name : DWORD VirtualQueryEx
646 * Purpose : The VirtualQueryEx function provides information about a range
647 * of pages within the virtual address space of a specified process.
648 * Parameters: HANDLE hProcess handle of process
649 * LPCVOID lpvAddress address of region
650 * LPMEMORY_BASIC_INFORMATION pmbiBuffer address of information buffer
651 * DWORD cbLength size of buffer
652 * Variables :
653 * Result : number of bytes returned in buffer
654 * Remark :
655 * Status : UNTESTED STUB
656 *
657 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
658 *****************************************************************************/
659
660ODINFUNCTION4(DWORD, VirtualQueryEx, HANDLE, hProcess,
661 LPCVOID, lpvAddress,
662 LPMEMORY_BASIC_INFORMATION, pmbiBuffer,
663 DWORD, cbLength)
664{
665 // only execute API, if this is the current process !
666 if (GetCurrentProcess() == hProcess)
667 return VirtualQuery(lpvAddress, pmbiBuffer, cbLength);
668 else
669 {
670 SetLastError(ERROR_ACCESS_DENIED); // deny access to other processes
671 return FALSE;
672 }
673}
Note: See TracBrowser for help on using the repository browser.