source: trunk/src/kernel32/mmap.cpp@ 2973

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

setcurrentdir fix + create shell dirs + keys during kernel32 init

File size: 21.2 KB
Line 
1/* $Id: mmap.cpp,v 1.35 2000-03-02 19:17:21 sandervl Exp $ */
2
3/*
4 * Win32 Memory mapped file & view classes
5 *
6 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * NOTE: Memory mapping DOES NOT work when kernel-mode code causes
9 * a pagefault in the memory mapped object. (exceptions aren't
10 * dispatched to our exception handler until after the kernel mode
11 * call returns (too late))
12 *
13 * NOTE: Are apps allowed to change the protection flags of memory mapped pages?
14 * I'm assuming they aren't for now.
15 *
16 * TODO: Handles returned should be usable by all apis that accept file handles
17 * TODO: Sharing memory mapped files between multiple processes
18 * TODO: Memory mapped files with views that extend the file (not 100% correct now)
19 *
20 * Project Odin Software License can be found in LICENSE.TXT
21 *
22 */
23#include <os2win.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <win\virtual.h>
28#include <vmutex.h>
29#include <handlemanager.h>
30#include "mmap.h"
31#include "oslibdos.h"
32#include <winimagepeldr.h>
33
34#define DBG_LOCALLOG DBG_mmap
35#include "dbglocal.h"
36
37//Global DLL Data
38#pragma data_seg(_GLOBALDATA)
39Win32MemMap *Win32MemMap::memmaps = NULL;
40VMutex globalmapMutex(VMUTEX_SHARED);
41#pragma data_seg()
42VMutex globalviewMutex;
43Win32MemMapView *Win32MemMapView::mapviews = NULL;
44
45//******************************************************************************
46//TODO: sharing between processes
47//******************************************************************************
48Win32MemMap::Win32MemMap(HFILE hfile, ULONG size, ULONG fdwProtect, LPSTR lpszName)
49 : nrMappings(0), pMapping(NULL), mMapAccess(0), referenced(0), image(0)
50{
51 globalmapMutex.enter();
52 next = memmaps;
53 memmaps = this;
54 globalmapMutex.leave();
55
56 hMemFile = hfile;
57
58 mSize = size;
59 mProtFlags = fdwProtect;
60 mProcessId = GetCurrentProcess();
61
62 if(lpszName) {
63 lpszMapName = (char *)_smalloc(strlen(lpszName)+1);
64 strcpy(lpszMapName, lpszName);
65 }
66 else lpszMapName = NULL;
67}
68//******************************************************************************
69//Map constructor used for executable image maps (only used internally)
70//******************************************************************************
71Win32MemMap::Win32MemMap(Win32PeLdrImage *pImage, ULONG baseAddress, ULONG size)
72 : nrMappings(0), pMapping(NULL), mMapAccess(0), referenced(0)
73{
74 globalmapMutex.enter();
75 next = memmaps;
76 memmaps = this;
77 globalmapMutex.leave();
78
79 hMemFile = -1;
80
81 mSize = size;
82 mProtFlags = PAGE_READWRITE;
83 mProcessId = GetCurrentProcess();
84
85 pMapping = (LPVOID)baseAddress;
86
87 image = pImage;
88 lpszMapName= NULL;
89}
90//******************************************************************************
91//******************************************************************************
92BOOL Win32MemMap::Init(HANDLE hMemMap)
93{
94 mapMutex.enter();
95 if(hMemFile != -1)
96 {
97 if(DuplicateHandle(mProcessId, hMemFile, GetCurrentProcess(),
98 &hMemFile, 0, FALSE, DUPLICATE_SAME_ACCESS) == FALSE)
99 {
100 dprintf(("Win32MemMap::Init: DuplicateHandle failed!"));
101 goto fail;
102 }
103 mSize = SetFilePointer(hMemFile, 0, NULL, FILE_END);
104 if(mSize == -1) {
105 dprintf(("Win32MemMap::init: SetFilePointer failed to set pos end"));
106 goto fail;
107 }
108 //SvL: Temporary limitation of size (Warp Server Advanced doesn't allow
109 // one to reserve more than 450 MB (unless you override the virtual
110 // memory max limit) of continuous memory; (Warp 4 much less))
111 if(mSize > 64*1024*1024) {
112 mSize = 64*1024*1024;
113 }
114 }
115
116 dprintf(("CreateFileMappingA for file %x, prot %x size %d, name %s", hMemFile, mProtFlags, mSize, lpszMapName));
117 this->hMemMap = hMemMap;
118 mapMutex.leave();
119 return TRUE;
120fail:
121 mapMutex.leave();
122 return FALSE;
123}
124//******************************************************************************
125//******************************************************************************
126Win32MemMap::~Win32MemMap()
127{
128 Win32MemMapView::deleteViews(this); //delete all views of our memory mapped file
129
130 dprintf(("Win32MemMap dtor: deleting view %x %x", pMapping, mSize));
131
132 mapMutex.enter();
133 if(lpszMapName) {
134 free(lpszMapName);
135 }
136 if(pMapping && !image) {
137 if(lpszMapName) {
138 OSLibDosFreeMem(pMapping);
139 }
140 else VirtualFree(pMapping, mSize, MEM_RELEASE);
141
142 pMapping = NULL;
143 }
144 if(hMemFile != -1) {
145 CloseHandle(hMemFile);
146 hMemFile = -1;
147 }
148 mapMutex.leave();
149
150 globalmapMutex.enter();
151 Win32MemMap *map = memmaps;
152
153 if(map == this) {
154 memmaps = next;
155 }
156 else {
157 while(map->next) {
158 if(map->next == this)
159 break;
160 map = map->next;
161 }
162 if(map->next) {
163 map->next = next;
164 }
165 else dprintf(("Win32MemMap::~Win32MemMap: map not found!! (%x)", this));
166 }
167 globalmapMutex.leave();
168}
169//******************************************************************************
170//We determine whether a page has been modified by checking it's protection flags
171//If the write flag is set, this means commitPage had to enable this due to a pagefault
172//(all pages are readonly until the app tries to write to it)
173//******************************************************************************
174BOOL Win32MemMap::commitPage(ULONG offset, BOOL fWriteAccess, int nrpages)
175{
176 MEMORY_BASIC_INFORMATION memInfo;
177 LPVOID lpPageFaultAddr = (LPVOID)((ULONG)pMapping + offset);
178 DWORD pageAddr = (DWORD)lpPageFaultAddr & ~0xFFF;
179 DWORD oldProt, newProt, nrBytesRead, size;
180 int i;
181
182// mapMutex.enter();
183
184 if(image) {
185 return image->commitPage(pageAddr, fWriteAccess);
186 }
187 newProt = mProtFlags & (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY);
188
189 dprintf(("Win32MemMap::commitPage %x (faultaddr %x)", pageAddr, lpPageFaultAddr));
190 if(hMemFile != -1) {
191// for(i=0;i<nrpages;i++) {
192 if(VirtualQuery((LPSTR)pageAddr, &memInfo, nrpages*PAGE_SIZE) == 0) {
193 dprintf(("Win32MemMap::commitPage: VirtualQuery (%x,%x) failed for %x", pageAddr, nrpages*PAGE_SIZE));
194 goto fail;
195 }
196 //Only changes the state of the pages with the same attribute flags
197 //(returned in memInfo.RegionSize)
198 //If it's smaller than the mNrPages, it simply means one or more of the
199 //other pages have already been committed
200 if(memInfo.State & MEM_COMMIT)
201 {//if it's already committed, then the app tried to write to it
202 if(!fWriteAccess) {
203 dprintf(("Win32MemMap::commitPage: Huh? Already committed and not trying to write (%x,%x) failed for %x", pageAddr, memInfo.RegionSize));
204 goto fail;
205 }
206 if(VirtualProtect((LPVOID)pageAddr, memInfo.RegionSize, newProt, &oldProt) == FALSE) {
207 dprintf(("Win32MemMap::commitPage: Failed to set write flag on page (%x,%x) failed for %x", pageAddr, memInfo.RegionSize));
208 goto fail;
209 }
210 }
211 else {
212 if(VirtualAlloc((LPVOID)pageAddr, memInfo.RegionSize, MEM_COMMIT, PAGE_READWRITE) == FALSE) {
213 goto fail;
214 }
215 if(!fWriteAccess) {
216 offset = pageAddr - (ULONG)pMapping;
217 size = memInfo.RegionSize;
218 if(offset + size > mSize) {
219 dprintf(("Adjusting size from %d to %d", size, mSize - offset));
220 size = mSize - offset;
221 }
222 if(SetFilePointer(hMemFile, offset, NULL, FILE_BEGIN) != offset) {
223 dprintf(("Win32MemMap::commitPage: SetFilePointer failed to set pos to %x", offset));
224 goto fail;
225 }
226 if(ReadFile(hMemFile, (LPSTR)pageAddr, size, &nrBytesRead, NULL) == FALSE) {
227 dprintf(("Win32MemMap::commitPage: ReadFile failed for %x", pageAddr));
228 goto fail;
229 }
230 if(nrBytesRead != size) {
231 dprintf(("Win32MemMap::commitPage: ReadFile didn't read all bytes for %x", pageAddr));
232 goto fail;
233 }
234 }
235 if(mProtFlags != PAGE_READWRITE) {
236 if(VirtualProtect((LPVOID)pageAddr, memInfo.RegionSize, newProt, &oldProt) == FALSE) {
237 goto fail;
238 }
239 }
240 }
241// pageAddr += PAGE_SIZE;
242// }
243 }
244 else {
245 ULONG sizeleft = nrpages*PAGE_SIZE;
246 while(sizeleft) {
247 if(VirtualQuery((LPSTR)pageAddr, &memInfo, sizeleft) == 0) {
248 dprintf(("Win32MemMap::commitPage: VirtualQuery (%x,%x) failed", pageAddr, sizeleft));
249 goto fail;
250 }
251 if(!(memInfo.State & MEM_COMMIT))
252 {//if it's already committed, then the app tried to write to it
253 if(VirtualAlloc((LPVOID)pageAddr, memInfo.RegionSize, MEM_COMMIT, newProt) == FALSE)
254 goto fail;
255 }
256 memInfo.RegionSize = (memInfo.RegionSize+PAGE_SIZE-1) & ~0xfff;
257 pageAddr += memInfo.RegionSize;
258 sizeleft -= memInfo.RegionSize;
259 }
260 }
261
262// mapMutex.leave();
263 return TRUE;
264fail:
265// mapMutex.leave();
266 return FALSE;
267}
268//******************************************************************************
269//******************************************************************************
270BOOL Win32MemMap::unmapViewOfFile(Win32MemMapView *view)
271{
272 dprintf(("Win32MemMap::unmapViewOfFile %x (nrmaps=%d)", view, nrMappings));
273 mapMutex.enter();
274
275 if(nrMappings == 0)
276 goto fail;
277
278 delete view;
279
280 if(--nrMappings == 0) {
281 VirtualFree(pMapping, mSize, MEM_RELEASE);
282 pMapping = NULL;
283 }
284 mapMutex.leave();
285 return TRUE;
286fail:
287 mapMutex.leave();
288 return FALSE;
289}
290//******************************************************************************
291//******************************************************************************
292LPVOID Win32MemMap::mapViewOfFile(ULONG size, ULONG offset, ULONG fdwAccess)
293{
294 DWORD processId = GetCurrentProcess();
295
296 mapMutex.enter();
297 ULONG memFlags = (mProtFlags & (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY));
298 ULONG fAlloc = 0;
299 Win32MemMapView *mapview;
300
301 //@@@PH: if(fdwAccess & ~(FILE_MAP_WRITE|FILE_MAP_READ|FILE_MAP_COPY))
302 // Docs say FILE_MAP_ALL_ACCESS is same as FILE_MAP_WRITE. Doesn't match reality though.
303 if(fdwAccess & ~FILE_MAP_ALL_ACCESS)
304 goto parmfail;
305 if((fdwAccess & FILE_MAP_WRITE) && !(mProtFlags & PAGE_READWRITE))
306 goto parmfail;
307 if((fdwAccess & FILE_MAP_READ) && !(mProtFlags & (PAGE_READWRITE|PAGE_READONLY)))
308 goto parmfail;
309
310 //@@@PH
311 if (fdwAccess != FILE_MAP_ALL_ACCESS)
312 if((fdwAccess & FILE_MAP_COPY) && !(mProtFlags & PAGE_WRITECOPY))
313 goto parmfail;
314
315 if(offset+size > mSize && (!(fdwAccess & FILE_MAP_WRITE) || !hMemFile))
316 goto parmfail;
317
318 //SvL: TODO: Doesn't work for multiple views
319 if(offset+size > mSize) {
320 mSize = offset+size;
321 }
322
323//TODO: If committed, read file into memory
324#if 0
325 if(mProtFlags & SEC_COMMIT)
326 fAlloc |= MEM_COMMIT;
327 else
328 if(mProtFlags & SEC_RESERVE)
329 fAlloc |= MEM_RESERVE;
330#else
331 fAlloc = MEM_RESERVE;
332#endif
333
334 //Memory has already been allocated for executable image maps (only used internally)
335 if(!pMapping && nrMappings == 0) {//if not mapped, reserve/commit entire view
336 //SvL: Always read/write access or else ReadFile will crash once we
337 // start committing pages.
338 // This is most likely an OS/2 bug and doesn't happen in Aurora
339 // when allocating memory with the PAG_ANY bit set. (without this
340 // flag it will also crash)
341 if(!hMemFile && lpszMapName) {
342 pMapping = VirtualAllocShared(mSize, fAlloc, PAGE_READWRITE, lpszMapName);
343 }
344 else {
345 pMapping = VirtualAlloc(0, mSize, fAlloc, PAGE_READWRITE);
346 }
347 if(pMapping == NULL) {
348 dprintf(("Win32MemMap::mapFileView: VirtualAlloc %x %x %x failed!", mSize, fAlloc, memFlags));
349 goto fail;
350 }
351 //Windows NT seems to commit memory for memory maps, regardsless of the SEC_COMMIT flag
352 if((hMemFile == -1 && !image)) {//commit memory
353 VirtualAlloc(pMapping, mSize, MEM_COMMIT, PAGE_READWRITE);
354 }
355 if(hMemFile && (mProtFlags & SEC_COMMIT)) {
356 DWORD nrPages = mSize >> PAGE_SHIFT;
357 if(mSize & 0xFFF)
358 nrPages++;
359
360 commitPage(0, FALSE, nrPages);
361 }
362 }
363 mapview = new Win32MemMapView(this, offset, (size == 0) ? mSize : size, fdwAccess);
364 if(mapview == NULL) {
365 goto fail;
366 }
367 if(mapview->everythingOk() == FALSE) {
368 dprintf(("Win32MemMap::mapFileView: !mapview->everythingOk"));
369 delete mapview;
370 goto fail;
371 }
372 nrMappings++;
373 mapMutex.leave();
374 return mapview->getViewAddr();
375
376parmfail:
377 dprintf(("Win32MemMap::mapFileView: ERROR_INVALID_PARAMETER"));
378 SetLastError(ERROR_INVALID_PARAMETER);
379fail:
380 mapMutex.leave();
381 return 0;
382}
383//******************************************************************************
384//We determine whether a page has been modified by checking it's protection flags
385//If the write flag is set, this means commitPage had to enable this due to a pagefault
386//(all pages are readonly until the app tries to modify the contents of the page)
387//
388//TODO: Are apps allowed to change the protection flags of memory mapped pages?
389// I'm assuming they aren't for now.
390//******************************************************************************
391BOOL Win32MemMap::flushView(ULONG offset, ULONG cbFlush)
392{
393 LPVOID lpvBase = (LPVOID)((ULONG)pMapping+offset);
394 MEMORY_BASIC_INFORMATION memInfo;
395 ULONG nrBytesWritten, size;
396 int i;
397
398 if(image) //no flushing for image maps
399 return TRUE;
400
401 dprintf(("Win32MemMap::flushView: %x %x", lpvBase, cbFlush));
402 if(nrMappings == 0)
403 goto parmfail;
404
405 if(cbFlush == 0)
406 cbFlush = mSize;
407
408 if(lpvBase < pMapping || (ULONG)lpvBase+cbFlush > (ULONG)pMapping+mSize)
409 goto parmfail;
410
411 if(mProtFlags & PAGE_READONLY)
412 goto parmfail;
413
414 if(hMemFile == -1)
415 goto success; //TODO: Return an error here?
416
417 while(cbFlush) {
418 if(VirtualQuery((LPSTR)lpvBase, &memInfo, cbFlush) == 0) {
419 dprintf(("Win32MemMap::flushView: VirtualQuery (%x,%x) failed for %x", lpvBase, cbFlush, (ULONG)lpvBase+i*PAGE_SIZE));
420 goto fail;
421 }
422 //If a page (or range of pages) is reserved or write protected, we
423 //won't bother flushing it to disk
424 if(memInfo.State & MEM_COMMIT &&
425 memInfo.AllocationProtect & (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY))
426 {//committed and allowed for writing?
427 offset = (ULONG)lpvBase - (ULONG)pMapping;
428 size = memInfo.RegionSize;
429 if(size > cbFlush) {
430 size = cbFlush;
431 }
432 dprintf(("Win32MemMap::flushView for offset %x, size %d", offset, size));
433
434 if(SetFilePointer(hMemFile, offset, NULL, FILE_BEGIN) != offset) {
435 dprintf(("Win32MemMap::flushView: SetFilePointer failed to set pos to %x", offset));
436 goto fail;
437 }
438 if(WriteFile(hMemFile, (LPSTR)lpvBase, size, &nrBytesWritten, NULL) == FALSE) {
439 dprintf(("Win32MemMap::flushView: WriteFile failed for %x", (ULONG)lpvBase));
440 goto fail;
441 }
442 if(nrBytesWritten != size) {
443 dprintf(("Win32MemMap::flushView: WriteFile didn't write all bytes for %x", (ULONG)lpvBase));
444 goto fail;
445 }
446 }
447 lpvBase = (LPVOID)((ULONG)lpvBase + memInfo.RegionSize);
448
449 if(cbFlush < memInfo.RegionSize)
450 break;
451
452 cbFlush -= memInfo.RegionSize;
453 }
454success:
455 return TRUE;
456parmfail:
457 SetLastError(ERROR_INVALID_PARAMETER);
458 return FALSE;
459fail:
460 return FALSE;
461}
462//******************************************************************************
463//******************************************************************************
464Win32MemMap *Win32MemMap::findMap(LPSTR lpszName)
465{
466 if(lpszName == NULL)
467 return NULL;
468
469 globalmapMutex.enter();
470 Win32MemMap *map = memmaps;
471
472 if(map != NULL) {
473 while(map) {
474 if(map->lpszMapName && !strcmp(map->lpszMapName, lpszName))
475 break;
476 map = map->next;
477 }
478 }
479 globalmapMutex.leave();
480 if(!map) dprintf(("Win32MemMap::findMap: couldn't find map %s", lpszName));
481 return map;
482}
483//******************************************************************************
484//******************************************************************************
485Win32MemMap *Win32MemMap::findMap(ULONG address)
486{
487 globalmapMutex.enter();
488 Win32MemMap *map = memmaps;
489
490 if(map != NULL) {
491 while(map) {
492 if(map->pMapping && (ULONG)map->pMapping <= address &&
493 (ULONG)map->pMapping + map->mSize > address)
494 {
495 break;
496 }
497 map = map->next;
498 }
499 }
500 globalmapMutex.leave();
501 return map;
502}
503//******************************************************************************
504//Assumes mutex has been acquired
505//******************************************************************************
506void Win32MemMap::deleteAll()
507{
508 Win32MemMap *map = memmaps, *nextmap;
509 DWORD processId = GetCurrentProcess();
510
511 //delete all maps created by this process
512 while(map) {
513 nextmap = map->next;
514 if(map->getProcessId() == processId) {
515 //Delete map directly for executable images (only used internally)
516 if(map->getImage()) {
517 delete map;
518 }
519 else CloseHandle(memmaps->hMemMap);
520 }
521 else {
522 //delete all views created by this process for this map
523 Win32MemMapView::deleteViews(map);
524 }
525 map = nextmap;
526 }
527}
528//******************************************************************************
529//******************************************************************************
530Win32MemMapView::Win32MemMapView(Win32MemMap *map, ULONG offset, ULONG size,
531 ULONG fdwAccess)
532{
533 LPVOID viewaddr = (LPVOID)((ULONG)map->getMappingAddr()+offset);
534 ULONG accessAttr = 0;
535 Win32MemMapView *tmpview = mapviews;
536
537 errorState = 0;
538 mParentMap = map;
539 mSize = size;
540 mOffset = offset;
541 mProcessId = GetCurrentProcess();
542
543 switch(fdwAccess) {
544 case FILE_MAP_READ:
545 accessAttr = PAG_READ;
546 mfAccess = MEMMAP_ACCESS_READ;
547 break;
548 case FILE_MAP_ALL_ACCESS:
549 case FILE_MAP_WRITE:
550 case FILE_MAP_WRITE|FILE_MAP_READ:
551 case FILE_MAP_COPY:
552 accessAttr = (PAG_READ|PAG_WRITE);
553 mfAccess = MEMMAP_ACCESS_READ | MEMMAP_ACCESS_WRITE;
554 break;
555 }
556 if(map->getMemName() != NULL && !map->getFileHandle()) {
557 //shared memory map, so map it into our address space
558 if(OSLibDosGetNamedSharedMem((LPVOID *)&viewaddr, map->getMemName()) != OSLIB_NOERROR) {
559 dprintf(("new OSLibDosGetNamedSharedMem FAILED"));
560 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
561 errorState = 1;
562 return;
563 }
564 }
565
566 //view == memory mapping for executable images (only used internally)
567 if(map->getImage()) {
568 pMapView = map->getMappingAddr();
569 }
570 else {
571 if(OSLibDosAliasMem(viewaddr, size, &pMapView, accessAttr) != OSLIB_NOERROR) {
572 dprintf(("new OSLibDosAliasMem FAILED"));
573 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
574 errorState = 1;
575 return;
576 }
577 }
578
579 dprintf(("Win32MemMapView::Win32MemMapView: created %x (alias for %x), size %d", pMapView, viewaddr, size));
580
581 globalviewMutex.enter();
582 if(tmpview == NULL || tmpview->getViewAddr() > pMapView) {
583 next = mapviews;
584 mapviews = this;
585 }
586 else {
587 while(tmpview->next) {
588 if(tmpview->next->getViewAddr() > pMapView) {
589 break;
590 }
591 tmpview = tmpview->next;
592 }
593 next = tmpview->next;
594 tmpview->next = this;
595 }
596 globalviewMutex.leave();
597}
598//******************************************************************************
599//******************************************************************************
600Win32MemMapView::~Win32MemMapView()
601{
602 if(errorState != 0)
603 return;
604
605 dprintf(("Win32MemMapView dtor: deleting view %x %x", mOffset, mSize));
606
607 if(mfAccess & MEMMAP_ACCESS_WRITE)
608 mParentMap->flushView(mOffset, mSize);
609
610 //Don't free memory for executable image map views (only used internally)
611 if(!mParentMap->getImage())
612 OSLibDosFreeMem(pMapView);
613
614 globalviewMutex.enter();
615 Win32MemMapView *view = mapviews;
616
617 if(view == this) {
618 mapviews = next;
619 }
620 else {
621 while(view->next) {
622 if(view->next == this)
623 break;
624 view = view->next;
625 }
626 if(view->next) {
627 view->next = next;
628 }
629 else dprintf(("Win32MemMapView::~Win32MemMapView: map not found!! (%x)", this));
630 }
631 globalviewMutex.leave();
632}
633//******************************************************************************
634//******************************************************************************
635void Win32MemMapView::deleteViews(Win32MemMap *map)
636{
637 globalviewMutex.enter();
638 Win32MemMapView *view = mapviews, *nextview;
639
640 if(view != NULL) {
641 while(view) {
642 nextview = view->next;
643 if(view->getParentMap() == map)
644 {
645 globalviewMutex.leave();
646 delete view;
647 globalviewMutex.enter();
648 }
649 view = nextview;
650 }
651 }
652 globalviewMutex.leave();
653}
654//******************************************************************************
655//******************************************************************************
656Win32MemMap *Win32MemMapView::findMapByView(ULONG address, ULONG *offset,
657 ULONG accessType,
658 Win32MemMapView **pView)
659{
660 globalviewMutex.enter();
661 Win32MemMapView *view = mapviews;
662
663 *offset = 0;
664
665 if(view != NULL) {
666 while(view && (ULONG)view->getViewAddr() <= address) {
667 if((ULONG)view->getViewAddr() <= address &&
668 (ULONG)view->getViewAddr() + view->getSize() > address &&
669 view->getAccessFlags() >= accessType)
670 {
671 *offset = view->getOffset() + (address - (ULONG)view->getViewAddr());
672 goto success;
673 }
674 view = view->next;
675 }
676 //failure if we get here
677 view = NULL;
678 }
679success:
680 if(view && !view->getParentMap()->isImageMap())
681 dprintf(("findMapByView %x %x -> %x off %x", address, accessType, view->getViewAddr(), *offset));
682
683 globalviewMutex.leave();
684 if(pView) *pView = view;
685 return (view) ? view->getParentMap() : NULL;
686}
687//******************************************************************************
688//******************************************************************************
689Win32MemMapView *Win32MemMapView::findView(LPVOID address)
690{
691 Win32MemMapView *view = mapviews;
692
693 if(view != NULL) {
694 while(view) {
695 if(view->getViewAddr() == address)
696 {
697 break;
698 }
699 view = view->next;
700 }
701 }
702 return view;
703}
704//******************************************************************************
705//******************************************************************************
706
Note: See TracBrowser for help on using the repository browser.