Ignore:
Timestamp:
Feb 27, 2003, 6:16:33 PM (22 years ago)
Author:
sandervl
Message:

VirtualAlloc: fixed handling of commit for a page range that is not entirely reserved (contains committed pages)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/virtual.cpp

    r9824 r9869  
    1 /* $Id: virtual.cpp,v 1.50 2003-02-18 18:48:55 sandervl Exp $ */
     1/* $Id: virtual.cpp,v 1.51 2003-02-27 17:16:33 sandervl Exp $ */
    22
    33/*
     
    176176    map = Win32MemMapView::findMapByView((ULONG)base, &offset, MEMMAP_ACCESS_READ);
    177177    if(map == NULL) {
    178         SetLastError( ERROR_FILE_NOT_FOUND );
     178        //This is what NT4, SP6 returns for an invalid view address
     179        SetLastError( ERROR_INVALID_ADDRESS );
    179180        return FALSE;
    180181    }
    181     ret = map->flushView(offset, cbFlush);
     182    ret = map->flushView((ULONG)base, offset, cbFlush);
    182183    map->Release();
    183184    return ret;
     
    274275                             DWORD  fdwProtect)
    275276{
    276     PVOID Address = lpvAddress;
     277    PVOID Address;
    277278    ULONG flag = 0, base;
     279    ULONG remainder;
    278280    DWORD rc;
    279281
     
    294296        return NULL;
    295297    }
     298
     299    //round address and size to page boundaries
     300    remainder  = (ULONG)lpvAddress & 0xFFF;
     301    lpvAddress = (LPVOID)((ULONG)lpvAddress & ~0xFFF);
     302    Address    = lpvAddress;
     303
     304    cbSize    += remainder;
     305    remainder  = cbSize & 0xFFF;
     306    cbSize    &= ~0xFFF;
     307    if(remainder)
     308        cbSize += PAGE_SIZE;
    296309
    297310    if(fdwAllocationType & MEM_COMMIT)
     
    320333
    321334    if(fdwProtect & PAGE_GUARD) {
    322         dprintf(("ERROR: PAGE_GUARD bit set for VirtualAlloc -> we don't support this right now!"));
     335        dprintf(("WARNING: PAGE_GUARD bit set for VirtualAlloc -> we don't support this right now!"));
    323336        flag |= PAG_GUARD;
    324337    }
     
    352365        if(map) {
    353366            //TODO: We don't allow protection flag changes for mmaped files now
    354             map->commitPage(offset, FALSE, nrpages);
     367            map->commitPage((ULONG)lpvAddress, offset, FALSE, nrpages);
    355368            map->Release();
    356369            return lpvAddress;
     
    363376        Address = lpvAddress;
    364377
     378        //try to commit the pages
    365379        rc = OSLibDosSetMem(lpvAddress, cbSize, flag);
    366380
    367381        //might try to commit larger part with same base address
    368         if(rc == OSLIB_ERROR_ACCESS_DENIED && cbSize > 4096 )
    369         { //knut: AND more than one page
    370             char *newbase = (char *)lpvAddress + ((cbSize-1) & 0xFFFFF000); //knut: lets not start after the last page!
    371             ULONG size, os2flags;
    372    
    373             while(newbase >= (char *)lpvAddress)
    374             {     //knut: should check first page to!!
    375                 size     = 4096;
    376                 os2flags = 0;
    377                 rc = OSLibDosQueryMem(newbase, &size, &os2flags);
    378                 if(rc)
    379                     break;
    380 
    381                 if(os2flags & PAG_COMMIT)
     382        if(rc == OSLIB_ERROR_ACCESS_DENIED && cbSize > PAGE_SIZE )
     383        {
     384            while(cbSize)
     385            {
     386                //check if the app tries to commit an already commited part of memory or change the protection flags
     387                ULONG size = cbSize, os2flags, newrc;
     388                newrc = OSLibDosQueryMem(lpvAddress, &size, &os2flags);
     389                if(newrc == 0)
    382390                {
    383                     newbase += 4096;
     391                    if(os2flags & PAG_COMMIT)
     392                    {
     393                        dprintf(("VirtualAlloc: commit on committed memory"));
     394                        if((flag & (PAG_READ|PAG_WRITE|PAG_EXECUTE)) != (os2flags & (PAG_READ|PAG_WRITE|PAG_EXECUTE)))
     395                        {   //change protection flags
     396                            DWORD tmp;
     397                            if(VirtualProtect(lpvAddress, size, fdwProtect, &tmp) == FALSE)
     398                            {
     399                                dprintf(("ERROR: VirtualAlloc: commit on committed memory -> VirtualProtect failed!!"));
     400                                return NULL;
     401                            }
     402                        }
     403                    }
     404                    else
     405                    {   //commit this page (or range of pages)
     406                        rc = OSLibDosSetMem(lpvAddress, size, flag);
     407                        if(rc) {
     408                            dprintf(("Unexpected DosSetMem error %x", rc));
     409                            break;
     410                        }
     411                    }
     412                }
     413                else {
     414                    dprintf(("Unexpected DosQueryMem error %x", newrc));
     415                    rc = newrc;
    384416                    break;
    385417                }
    386                 newbase -= 4096;
    387             }
    388 
    389             if(rc == 0)
    390             {
    391                 //In case it wants to commit bytes that fall into the last
    392                 //page of the previous commit command
    393                 if(cbSize > ((int)newbase - (int)lpvAddress))
    394                     rc = OSLibDosSetMem(newbase, cbSize - ((int)newbase - (int)lpvAddress), flag);
    395             }
    396             else  return(NULL);
     418                cbSize -= size;
     419
     420                lpvAddress = (LPVOID)((char *)lpvAddress + size);
     421            }//while(cbSize)
     422
     423            rc = 0; //success
    397424        }
    398425        else
     
    443470
    444471    dprintf(("VirtualAlloc returned %X\n", Address));
     472    SetLastError(ERROR_SUCCESS);
    445473    return(Address);
    446474}
Note: See TracChangeset for help on using the changeset viewer.