Changeset 705 for trunk/src/kernel32/virtual.cpp
- Timestamp:
- Aug 26, 1999, 2:56:02 PM (26 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/virtual.cpp
r690 r705 1 /* $Id: virtual.cpp,v 1. 7 1999-08-25 14:27:07 sandervl Exp $ */1 /* $Id: virtual.cpp,v 1.8 1999-08-26 12:55:37 sandervl Exp $ */ 2 2 3 3 /* 4 4 * Win32 virtual memory functions 5 5 * 6 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl) 6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl) 7 * Copyright 1998 Knut St. Osmundsen 8 * Copyright 1998 Peter FitzSimmons 7 9 * 8 10 * Parts (VIRTUAL_MapFileA/W) based on Wine code (memory\virtual.c): … … 21 23 #include <handlemanager.h> 22 24 #include "mmap.h" 25 #include "oslibdos.h" 23 26 24 27 /*********************************************************************** … … 239 242 return hMapping; 240 243 } 244 245 //****************************************************************************** 246 //****************************************************************************** 247 LPVOID WIN32API VirtualAlloc(LPVOID lpvAddress, DWORD cbSize, DWORD fdwAllocationType, 248 DWORD fdwProtect) 249 { 250 PVOID Address = lpvAddress; 251 ULONG flag = 0, base; 252 APIRET rc; 253 254 dprintf(("VirtualAlloc at %X; %d bytes, fAlloc %d, fProtect %d\n", (int)lpvAddress, cbSize, fdwAllocationType, fdwProtect)); 255 256 if (cbSize > 0x7fc00000) /* 2Gb - 4Mb */ 257 { 258 dprintf(("VirtualAlloc: size too large")); 259 SetLastError( ERROR_OUTOFMEMORY ); 260 return NULL; 261 } 262 263 if (!(fdwAllocationType & (MEM_COMMIT | MEM_RESERVE)) || 264 (fdwAllocationType & ~(MEM_COMMIT | MEM_RESERVE))) 265 { 266 dprintf(("VirtualAlloc: Invalid parameter")); 267 SetLastError( ERROR_INVALID_PARAMETER ); 268 return NULL; 269 } 270 271 if(fdwAllocationType & MEM_COMMIT) { 272 dprintf(("VirtualAlloc: commit\n")); 273 flag = PAG_COMMIT; 274 } 275 if(fdwProtect & PAGE_READONLY) flag |= PAG_READ; 276 if(fdwProtect & PAGE_READWRITE) flag |= (PAG_READ | PAG_WRITE); 277 if(fdwProtect & PAGE_WRITECOPY) flag |= (PAG_READ | PAG_WRITE); 278 279 if(fdwProtect & PAGE_EXECUTE_READWRITE) flag |= (PAG_EXECUTE | PAG_WRITE | PAG_READ); 280 if(fdwProtect & PAGE_EXECUTE_READ) flag |= (PAG_EXECUTE | PAG_READ); 281 if(fdwProtect & PAGE_EXECUTE) flag |= PAG_EXECUTE; 282 283 if(fdwProtect & PAGE_GUARD) flag |= PAG_GUARD; 284 285 //just do this if other options are used 286 if(!(flag & (PAG_READ | PAG_WRITE | PAG_EXECUTE)) || flag == 0) 287 { 288 dprintf(("VirtualAlloc: Unknown protection flags, default to read/write")); 289 flag |= PAG_READ | PAG_WRITE; 290 } 291 292 if(fdwAllocationType & MEM_COMMIT && lpvAddress != NULL) 293 { 294 Address = lpvAddress; 295 296 rc = OSLibDosSetMem(lpvAddress, cbSize, flag); 297 298 //might try to commit larger part with same base address 299 if(rc == OSLIB_ERROR_ACCESS_DENIED && cbSize > 4096 ) 300 { //knut: AND more than one page 301 char *newbase = (char *)lpvAddress + ((cbSize-1) & 0xFFFFF000); //knut: lets not start after the last page! 302 ULONG size, os2flags; 303 304 while(newbase >= (char *)lpvAddress) 305 { //knut: should check first page to!! 306 size = 4096; 307 os2flags = 0; 308 rc = OSLibDosQueryMem(newbase, &size, &os2flags); 309 if(rc) 310 break; 311 312 if(os2flags & PAG_COMMIT) 313 { 314 newbase += 4096; 315 break; 316 } 317 newbase -= 4096; 318 } 319 320 if(rc == 0) 321 { 322 //In case it wants to commit bytes that fall into the last 323 //page of the previous commit command 324 if(cbSize > ((int)newbase - (int)lpvAddress)) 325 rc = OSLibDosSetMem(newbase, cbSize - ((int)newbase - (int)lpvAddress), flag); 326 } 327 else return(NULL); 328 329 } 330 else 331 { 332 if(rc == OSLIB_ERROR_INVALID_ADDRESS) { 333 rc = OSLibDosAllocMem(&Address, cbSize, flag ); 334 } 335 else 336 if(rc) dprintf(("Unexpected DosSetMem error %x", rc)); 337 } 338 } 339 else 340 { 341 rc = OSLibDosAllocMem(&Address, cbSize, flag); 342 } 343 344 if(rc) 345 { 346 dprintf(("DosSetMem returned %d\n", rc)); 347 SetLastError( ERROR_OUTOFMEMORY ); 348 return(NULL); 349 } 350 351 dprintf(("VirtualAlloc returned %X\n", Address)); 352 return(Address); 353 } 354 //****************************************************************************** 355 //****************************************************************************** 356 BOOL WIN32API VirtualFree(LPVOID lpvAddress, DWORD cbSize, DWORD FreeType) 357 { 358 APIRET rc; 359 360 dprintf(("VirtualFree at %d; %d bytes, freetype %d\n", (int)lpvAddress, cbSize, FreeType)); 361 362 if(lpvAddress == NULL || cbSize == 0) { 363 SetLastError(ERROR_INVALID_PARAMETER); 364 return(FALSE); 365 } 366 if(FreeType & MEM_DECOMMIT) { 367 rc = OSLibDosSetMem(lpvAddress, cbSize, PAG_DECOMMIT); 368 } 369 else rc = OSLibDosFreeMem(lpvAddress); //MEM_RELEASE, cbSize == 0 (or should be) 370 371 if(rc) { 372 SetLastError(ERROR_GEN_FAILURE); 373 return(FALSE); 374 } 375 return(TRUE); 376 } 377 //****************************************************************************** 378 //LPVOID lpvAddress; /* address of region of committed pages */ 379 //DWORD cbSize; /* size of the region */ 380 //DWORD fdwNewProtect; /* desired access protection */ 381 //PDWORD pfdwOldProtect; /* address of variable to get old protection */ 382 //TODO: Not 100% complete 383 //TODO: SetLastError on failure 384 //****************************************************************************** 385 BOOL WIN32API VirtualProtect(LPVOID lpvAddress, DWORD cbSize, DWORD fdwNewProtect, 386 DWORD *pfdwOldProtect) 387 { 388 APIRET rc; 389 ULONG pageFlags = 0; 390 int npages; 391 392 dprintf(("VirtualProtect %X; %d bytes, new flags %X (%X)\n", (int)lpvAddress, cbSize, fdwNewProtect, pfdwOldProtect)); 393 if(pfdwOldProtect == NULL) 394 return(FALSE); 395 396 rc = OSLibDosQueryMem(lpvAddress, &cbSize, &pageFlags); 397 if(rc) { 398 dprintf(("DosQueryMem returned %d\n", rc)); 399 return(FALSE); 400 } 401 dprintf(("Old memory flags %X\n", pageFlags)); 402 *pfdwOldProtect = 0; 403 if(pageFlags & PAG_READ && !(pageFlags & PAG_WRITE)) 404 *pfdwOldProtect |= PAGE_READONLY; 405 if(pageFlags & (PAG_WRITE)) 406 *pfdwOldProtect |= PAGE_READWRITE; 407 408 if(pageFlags & (PAG_WRITE | PAG_EXECUTE)) 409 *pfdwOldProtect |= PAGE_EXECUTE_READWRITE; 410 else 411 if(pageFlags & PAG_EXECUTE) 412 *pfdwOldProtect |= PAGE_EXECUTE_READ; 413 414 if(pageFlags & PAG_GUARD) 415 *pfdwOldProtect |= PAGE_GUARD; 416 pageFlags = 0; 417 418 if(fdwNewProtect & PAGE_READONLY) pageFlags |= PAG_READ; 419 if(fdwNewProtect & PAGE_READWRITE) pageFlags |= (PAG_READ | PAG_WRITE); 420 if(fdwNewProtect & PAGE_WRITECOPY) pageFlags |= (PAG_READ | PAG_WRITE); 421 if(fdwNewProtect & PAGE_EXECUTE_READ) pageFlags |= (PAG_EXECUTE | PAG_READ); 422 if(fdwNewProtect & PAGE_EXECUTE_READWRITE) 423 pageFlags |= (PAG_EXECUTE | PAG_WRITE | PAG_READ); 424 if(fdwNewProtect & PAGE_EXECUTE_WRITECOPY) 425 pageFlags |= (PAG_EXECUTE | PAG_WRITE | PAG_READ); 426 if(fdwNewProtect & PAGE_GUARD) pageFlags |= PAG_GUARD; 427 //Not supported in OS/2?? 428 // if(fdwNewProtect & PAGE_NOACCESS) 429 430 dprintf(("New memory flags %X\n", pageFlags)); 431 if(pageFlags == 0) { 432 dprintf(("pageFlags == 0\n")); 433 return(TRUE); //nothing to do 434 } 435 npages = ((int)lpvAddress + cbSize >> 12) - ((int)lpvAddress >> 12) + 1; 436 437 lpvAddress = (LPVOID)((int)lpvAddress & ~0xFFF); 438 cbSize = npages*4096; 439 dprintf(("lpvAddress = %X, cbSize = %d\n", lpvAddress, cbSize)); 440 441 rc = OSLibDosSetMem(lpvAddress, cbSize, pageFlags); 442 if(rc) { 443 dprintf(("DosSetMem returned %d\n", rc)); 444 return(FALSE); 445 } 446 return(TRUE); 447 } 448 //****************************************************************************** 449 //****************************************************************************** 450 DWORD WIN32API VirtualQuery(LPCVOID lpvAddress, LPMEMORY_BASIC_INFORMATION pmbiBuffer, 451 DWORD cbLength) 452 { 453 ULONG cbRangeSize, dAttr; 454 APIRET rc; 455 456 if(lpvAddress == NULL || pmbiBuffer == NULL || cbLength == 0) { 457 return 0; 458 } 459 cbRangeSize = cbLength; 460 rc = OSLibDosQueryMem((LPVOID)lpvAddress, &cbRangeSize, &dAttr); 461 if(rc) { 462 dprintf(("VirtualQuery - DosQueryMem %x %x returned %d\n", lpvAddress, cbLength, rc)); 463 return 0; 464 } 465 memset(pmbiBuffer, 0, sizeof(MEMORY_BASIC_INFORMATION)); 466 pmbiBuffer->BaseAddress = (LPVOID)lpvAddress; 467 pmbiBuffer->RegionSize = cbRangeSize; 468 if(dAttr & PAG_READ && !(dAttr & PAG_WRITE)) 469 pmbiBuffer->Protect |= PAGE_READONLY; 470 if(dAttr & PAG_WRITE) 471 pmbiBuffer->Protect |= PAGE_READWRITE; 472 473 if(dAttr & (PAG_WRITE | PAG_EXECUTE)) 474 pmbiBuffer->Protect |= PAGE_EXECUTE_READWRITE; 475 else 476 if(dAttr & PAG_EXECUTE) 477 pmbiBuffer->Protect |= PAGE_EXECUTE_READ; 478 479 if(dAttr & PAG_GUARD) 480 pmbiBuffer->Protect |= PAGE_GUARD; 481 482 if(dAttr & PAG_FREE) 483 pmbiBuffer->State = MEM_FREE; 484 else 485 if(dAttr & PAG_COMMIT) 486 pmbiBuffer->State = MEM_COMMIT; 487 else pmbiBuffer->State = MEM_RESERVE; 488 489 if(!(dAttr & PAG_SHARED)) 490 pmbiBuffer->Type = MEM_PRIVATE; 491 492 //TODO: This is not correct: AllocationProtect should contain the protection 493 // flags used in the initial call to VirtualAlloc 494 pmbiBuffer->AllocationProtect = pmbiBuffer->Protect; 495 if(dAttr & PAG_BASE) { 496 pmbiBuffer->AllocationBase = (LPVOID)lpvAddress; 497 } 498 else { 499 while(lpvAddress > 0) { 500 rc = OSLibDosQueryMem((LPVOID)lpvAddress, &cbRangeSize, &dAttr); 501 if(rc) { 502 dprintf(("VirtualQuery - OSLibDosQueryMem %x %x returned %d\n", lpvAddress, cbLength, rc)); 503 break; 504 } 505 if(dAttr & PAG_BASE) { 506 pmbiBuffer->AllocationBase = (LPVOID)lpvAddress; 507 break; 508 } 509 lpvAddress = (LPVOID)((ULONG)lpvAddress - PAGE_SIZE); 510 } 511 } 512 return sizeof(MEMORY_BASIC_INFORMATION); 513 } 514 //****************************************************************************** 515 //****************************************************************************** 516 BOOL WIN32API VirtualLock( LPVOID lpAddress, DWORD dwSize ) 517 { 518 dprintf(("VirtualLock at %d; %d bytes - stub (TRUE)\n", (int)lpAddress, dwSize)); 519 return TRUE; 520 } 521 522 //****************************************************************************** 523 BOOL WIN32API VirtualUnlock( LPVOID lpAddress, DWORD dwSize ) 524 { 525 dprintf(("VirtualUnlock at %d; %d bytes - stub (TRUE)\n", (int)lpAddress, dwSize)); 526 return TRUE; 527 } 528 529 /***************************************************************************** 530 * Name : BOOL VirtualProtectEx 531 * Purpose : The VirtualProtectEx function changes the access protection on 532 * a region of committed pages in the virtual address space of a specified 533 * process. Note that this function differs from VirtualProtect, 534 * which changes the access protection on the calling process only. 535 * Parameters: HANDLE hProcess handle of process 536 * LPVOID lpvAddress address of region of committed pages 537 * DWORD cbSize size of region 538 * DWORD fdwNewProtect desired access protection 539 * PDWORD pfdwOldProtect address of variable to get old protection 540 * Variables : 541 * Result : size of target buffer 542 * Remark : 543 * Status : UNTESTED STUB 544 * 545 * Author : Patrick Haller [Mon, 1998/06/15 08:00] 546 *****************************************************************************/ 547 548 BOOL WIN32API VirtualProtectEx(HANDLE hProcess, 549 LPVOID lpvAddress, 550 DWORD cbSize, 551 DWORD fdwNewProtect, 552 LPDWORD pfdwOldProtect) 553 { 554 dprintf(("KERNEL32: VirtualProtectEx(%08x,%08xh,%08xh,%08xh,%08xh) not implemented for different processes.\n", 555 hProcess, 556 lpvAddress, 557 cbSize, 558 fdwNewProtect, 559 pfdwOldProtect)); 560 561 return VirtualProtect(lpvAddress, cbSize, fdwNewProtect, pfdwOldProtect); 562 } 563 564 565 /***************************************************************************** 566 * Name : DWORD VirtualQueryEx 567 * Purpose : The VirtualQueryEx function provides information about a range 568 * of pages within the virtual address space of a specified process. 569 * Parameters: HANDLE hProcess handle of process 570 * LPCVOID lpvAddress address of region 571 * LPMEMORY_BASIC_INFORMATION pmbiBuffer address of information buffer 572 * DWORD cbLength size of buffer 573 * Variables : 574 * Result : number of bytes returned in buffer 575 * Remark : 576 * Status : UNTESTED STUB 577 * 578 * Author : Patrick Haller [Mon, 1998/06/15 08:00] 579 *****************************************************************************/ 580 581 DWORD WIN32API VirtualQueryEx(HANDLE hProcess, 582 LPCVOID lpvAddress, 583 LPMEMORY_BASIC_INFORMATION pmbiBuffer, 584 DWORD cbLength) 585 { 586 dprintf(("KERNEL32: VirtualQueryEx(%08x,%08xh,%08xh,%08xh) not implemented for different processes.\n", 587 hProcess, 588 lpvAddress, 589 pmbiBuffer, 590 cbLength)); 591 592 return VirtualQuery(lpvAddress, pmbiBuffer, cbLength); 593 } 594 //****************************************************************************** 595 //******************************************************************************
Note:
See TracChangeset
for help on using the changeset viewer.