Changeset 4534 for trunk/src/kernel32/virtual.cpp
- Timestamp:
- Oct 26, 2000, 7:21:39 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/virtual.cpp
r4279 r4534 1 /* $Id: virtual.cpp,v 1.3 4 2000-09-18 19:26:16sandervl Exp $ */1 /* $Id: virtual.cpp,v 1.35 2000-10-26 17:21:39 sandervl Exp $ */ 2 2 3 3 /* … … 28 28 #include "oslibdos.h" 29 29 30 #define DBG_LOCALLOG 30 #define DBG_LOCALLOG DBG_virtual 31 31 #include "dbglocal.h" 32 32 … … 40 40 * 41 41 * RETURNS 42 * 43 * 44 * 42 * Handle: Success 43 * 0: Mapping object does not exist 44 * NULL: Failure 45 45 */ 46 46 HANDLE WINAPI CreateFileMappingA( … … 82 82 * 83 83 * RETURNS 84 * 85 * 84 * Handle: Success 85 * NULL: Failure 86 86 */ 87 87 HANDLE WINAPI OpenFileMappingA( … … 113 113 * 114 114 * RETURNS 115 * 116 * 115 * Starting address of mapped view 116 * NULL: Failure 117 117 */ 118 118 LPVOID WINAPI MapViewOfFile( … … 134 134 * 135 135 * RETURNS 136 * 137 * 136 * Starting address of mapped view 137 * NULL: Failure 138 138 */ 139 139 LPVOID WINAPI MapViewOfFileEx( … … 155 155 * 156 156 * RETURNS 157 * 158 * 157 * TRUE: Success 158 * FALSE: Failure 159 159 */ 160 160 BOOL WINAPI FlushViewOfFile( … … 185 185 * 186 186 * NOTES 187 * 187 * Should addr be an LPCVOID? 188 188 * 189 189 * RETURNS 190 * 191 * 190 * TRUE: Success 191 * FALSE: Failure 192 192 */ 193 193 BOOL WINAPI UnmapViewOfFile(LPVOID addr /* [in] Address where mapped view begins */ … … 216 216 * 217 217 * Helper function to map a file to memory: 218 * name -file name219 * [RETURN] ptr -pointer to mapped file218 * name - file name 219 * [RETURN] ptr - pointer to mapped file 220 220 */ 221 221 HANDLE WINAPI VIRTUAL_MapFileW( LPCWSTR name , LPVOID *lpMapping, BOOL fReadIntoMemory) … … 241 241 * 242 242 * Helper function to map a file to memory: 243 * name -file name244 * [RETURN] ptr -pointer to mapped file243 * name - file name 244 * [RETURN] ptr - pointer to mapped file 245 245 */ 246 246 HANDLE WINAPI VIRTUAL_MapFileA( LPCSTR name , LPVOID *lpMapping, BOOL fReadIntoMemory) … … 277 277 if (cbSize > 0x7fc00000) /* 2Gb - 4Mb */ 278 278 { 279 279 dprintf(("VirtualAlloc: size too large")); 280 280 SetLastError( ERROR_OUTOFMEMORY ); 281 281 return NULL; … … 285 285 (fdwAllocationType & ~(MEM_COMMIT | MEM_RESERVE))) 286 286 { 287 287 dprintf(("VirtualAlloc: Invalid parameter")); 288 288 SetLastError( ERROR_INVALID_PARAMETER ); 289 289 return NULL; … … 295 295 flag = PAG_COMMIT; 296 296 } 297 297 298 298 if(fdwAllocationType & MEM_RESERVE) { 299 299 //SvL: DosRead crashes if memory is initially reserved with write 300 300 // access disabled (OS/2 bug) even if the commit sets the page 301 301 // flags to read/write: 302 303 304 305 flag |= PAG_READ|PAG_WRITE; 302 // DosSetMem does not alter the 16 bit selectors so if you change memory 303 // attributes and then access the memory with a 16 bit API (such as DosRead), 304 // it will have the old (alloc time) attributes 305 flag |= PAG_READ|PAG_WRITE; 306 306 } 307 307 if(fdwProtect & PAGE_READONLY) flag |= PAG_READ; … … 315 315 316 316 if(fdwProtect & PAGE_GUARD) { 317 317 dprintf(("ERROR: PAGE_GUARD bit set for VirtualAlloc -> we don't support this right now!")); 318 318 flag |= PAG_GUARD; 319 319 } … … 326 326 } 327 327 328 if(lpvAddress) 328 if(lpvAddress) 329 329 { 330 330 Win32MemMap *map; 331 331 ULONG offset, nrpages, accessflags = 0; 332 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 333 nrpages = cbSize >> PAGE_SHIFT; 334 if(cbSize & 0xFFF) 335 nrpages++; 336 337 if(flag & PAG_READ) { 338 accessflags |= MEMMAP_ACCESS_READ; 339 } 340 if(flag & PAG_WRITE) { 341 accessflags |= MEMMAP_ACCESS_WRITE; 342 } 343 if(flag & PAG_EXECUTE) { 344 accessflags |= MEMMAP_ACCESS_EXECUTE; 345 } 346 map = Win32MemMapView::findMapByView((ULONG)lpvAddress, &offset, accessflags); 347 if(map) { 348 //TODO: We don't allow protection flag changes for mmaped files now 349 map->commitPage(offset, FALSE, nrpages); 350 return lpvAddress; 351 } 352 352 } 353 353 … … 362 362 if(rc == OSLIB_ERROR_ACCESS_DENIED && cbSize > 4096 ) 363 363 { //knut: AND more than one page 364 char *newbase = (char *)lpvAddress + ((cbSize-1) & 0xFFFFF000); //knut: lets not start after the last page! 365 ULONG size, os2flags; 366 367 while(newbase >= (char *)lpvAddress) 368 { //knut: should check first page to!! 369 size = 4096; 370 os2flags = 0; 371 rc = OSLibDosQueryMem(newbase, &size, &os2flags); 372 if(rc) 373 break; 374 375 if(os2flags & PAG_COMMIT) 364 char *newbase = (char *)lpvAddress + ((cbSize-1) & 0xFFFFF000); //knut: lets not start after the last page! 365 ULONG size, os2flags; 366 367 while(newbase >= (char *)lpvAddress) 368 { //knut: should check first page to!! 369 size = 4096; 370 os2flags = 0; 371 rc = OSLibDosQueryMem(newbase, &size, &os2flags); 372 if(rc) 373 break; 374 375 if(os2flags & PAG_COMMIT) 376 { 377 newbase += 4096; 378 break; 379 } 380 newbase -= 4096; 381 } 382 383 if(rc == 0) 376 384 { 377 newbase += 4096; 378 break; 385 //In case it wants to commit bytes that fall into the last 386 //page of the previous commit command 387 if(cbSize > ((int)newbase - (int)lpvAddress)) 388 rc = OSLibDosSetMem(newbase, cbSize - ((int)newbase - (int)lpvAddress), flag); 379 389 } 380 newbase -= 4096; 381 } 382 383 if(rc == 0) 384 { 385 //In case it wants to commit bytes that fall into the last 386 //page of the previous commit command 387 if(cbSize > ((int)newbase - (int)lpvAddress)) 388 rc = OSLibDosSetMem(newbase, cbSize - ((int)newbase - (int)lpvAddress), flag); 389 } 390 else return(NULL); 390 else return(NULL); 391 391 392 392 } 393 393 else 394 394 { 395 if(rc == OSLIB_ERROR_INVALID_ADDRESS) { 396 rc = OSLibDosAllocMem(&Address, cbSize, flag ); 397 } 398 else 399 if(rc) dprintf(("Unexpected DosSetMem error %x", rc)); 395 if(rc == OSLIB_ERROR_INVALID_ADDRESS) { 396 rc = OSLibDosAllocMem(&Address, cbSize, flag ); 397 } 398 else { 399 if(rc) { 400 //check if the app tries to commit an already commited part of memory or change the protection flags 401 ULONG size = cbSize, os2flags, newrc; 402 newrc = OSLibDosQueryMem(lpvAddress, &size, &os2flags); 403 if(newrc == 0) { 404 if(size >= cbSize && (os2flags & PAG_COMMIT)) { 405 dprintf(("VirtualAlloc: commit on committed memory")); 406 if((flag & (PAG_READ|PAG_WRITE|PAG_EXECUTE)) != (os2flags & (PAG_READ|PAG_WRITE|PAG_EXECUTE))) 407 { //change protection flags 408 DWORD tmp; 409 if(VirtualProtect(lpvAddress, cbSize, fdwAllocationType, &tmp) == TRUE) { 410 return lpvAddress; 411 } 412 dprintf(("ERROR: VirtualAlloc: commit on committed memory -> VirtualProtect failed!!")); 413 return NULL; 414 } 415 //else everything ok 416 return lpvAddress; 417 } 418 else dprintf(("Unexpected DosSetMem error %x", rc)); 419 } 420 else { 421 dprintf(("Unexpected DosQueryMem error %x", newrc)); 422 } 423 } 424 } 400 425 } 401 426 } … … 446 471 if(rc) 447 472 { 448 449 450 451 452 453 454 473 if(rc == 32803) { //SvL: ERROR_ALIAS 474 dprintf(("KERNEL32:VirtualFree:OsLibSetMem rc = #%d; app tries to decommit aliased memory; ignore", rc)); 475 return(TRUE); 476 } 477 dprintf(("KERNEL32:VirtualFree:OsLibSetMem rc = #%d\n", rc)); 478 SetLastError(ERROR_INVALID_ADDRESS); 479 return(FALSE); 455 480 } 456 481 } … … 492 517 if(pfdwOldProtect == NULL) { 493 518 dprintf(("WARNING: pfdwOldProtect == NULL")); 494 519 SetLastError(ERROR_INVALID_PARAMETER); 495 520 return(FALSE); 496 521 } … … 542 567 cb = (cbSize & 0xFFF) + offset; // !!! added, some optimization :) 543 568 if( cb > 0 ) { // changed 544 569 npages++; 545 570 } 546 571 if( cb > 4096 ) { // changed, note '>' sign ( not '>=' ) 4096 is exactly one page 547 572 npages++; 548 573 } 549 574 … … 574 599 if(pmbiBuffer == NULL || cbLength != sizeof(MEMORY_BASIC_INFORMATION)) // check parameters 575 600 { 576 577 578 601 dprintf(("WARNING: invalid parameter")); 602 SetLastError(ERROR_INVALID_PARAMETER); 603 return 0; // nothing to return 579 604 } 580 605 … … 588 613 if(rc) 589 614 { 590 591 592 593 615 dprintf(("VirtualQuery - OSLibDosQueryMem %x %x returned %d\n", 616 lpBase, cbLength, rc)); 617 SetLastError(ERROR_INVALID_PARAMETER); 618 return 0; 594 619 } 595 620 … … 625 650 626 651 if(!(dAttr & PAG_SHARED)) 627 652 pmbiBuffer->Type = MEM_PRIVATE; 628 653 629 654 //TODO: This is not correct: AllocationProtect should contain the protection … … 631 656 pmbiBuffer->AllocationProtect = pmbiBuffer->Protect; 632 657 if(dAttr & PAG_BASE) { 633 658 pmbiBuffer->AllocationBase = lpBase; 634 659 } 635 660 else 636 661 { 637 638 639 640 641 642 643 644 645 646 647 648 649 650 662 while(lpBase > 0) 663 { 664 rc = OSLibDosQueryMem(lpBase, &cbRangeSize, &dAttr); 665 if(rc) { 666 dprintf(("VirtualQuery - OSLibDosQueryMem %x %x returned %d\n", 667 lpBase, cbLength, rc)); 668 break; 669 } 670 if(dAttr & PAG_BASE) { 671 pmbiBuffer->AllocationBase = lpBase; 672 break; 673 } 674 lpBase = (LPVOID)((ULONG)lpBase - PAGE_SIZE); 675 } 651 676 } 652 677 return sizeof(MEMORY_BASIC_INFORMATION); … … 752 777 if (cbSize > 0x7fc00000) /* 2Gb - 4Mb */ 753 778 { 754 779 dprintf(("VirtualAllocShared: size too large")); 755 780 SetLastError( ERROR_OUTOFMEMORY ); 756 781 return NULL; … … 760 785 (fdwAllocationType & ~(MEM_COMMIT | MEM_RESERVE))) 761 786 { 762 787 dprintf(("VirtualAllocShared: Invalid parameter")); 763 788 SetLastError( ERROR_INVALID_PARAMETER ); 764 789 return NULL; … … 781 806 782 807 if(fdwProtect & PAGE_GUARD) { 783 808 dprintf(("ERROR: PAGE_GUARD bit set for VirtualAllocShared -> we don't support this right now!")); 784 809 flag |= PAG_GUARD; 785 810 }
Note:
See TracChangeset
for help on using the changeset viewer.