Ignore:
Timestamp:
Jun 18, 2009, 11:53:26 AM (16 years ago)
Author:
ydario
Message:

Kernel32 updates.

File:
1 edited

Legend:

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

    r9945 r21302  
    3232#include <winconst.h>
    3333#include <win\winioctl.h>
    34 #include <misc.h>
     34#include <dbglog.h>
     35#include <vmutex.h>
    3536#include "initterm.h"
    3637#include "oslibdos.h"
     
    3839#include "dosqss.h"
    3940#include "win32k.h"
     41#include "exceptstackdump.h"
    4042
    4143#define DBG_LOCALLOG    DBG_oslibmem
    4244#include "dbglocal.h"
    4345
     46#include <_ras.h>
     47
     48#ifdef RAS
     49RAS_TRACK_HANDLE rthVirtual = 0;
     50
     51void rasInitVirtual (void)
     52{
     53    RasRegisterObjectTracking (&rthVirtual, "Virtual* memory allocation",
     54                               0, RAS_TRACK_FLAG_MEMORY | RAS_TRACK_FLAG_LOG_OBJECTS_AT_EXIT,
     55                               NULL, NULL);
     56}
     57#endif
     58
     59typedef struct _VirtAllocRec {
     60  ULONG baseaddr;
     61  ULONG size;
     62  ULONG attr;
     63
     64  struct _VirtAllocRec *next;
     65} VirtAllocRec;
     66
     67static VirtAllocRec         *allocrecords  = NULL;
     68static CRITICAL_SECTION_OS2  alloccritsect = {0};
     69
     70//******************************************************************************
     71//******************************************************************************
     72void AddAllocRec(ULONG baseaddr, ULONG size, ULONG attr)
     73{
     74    VirtAllocRec *rec, *tmp;
     75
     76    rec = (VirtAllocRec *)malloc(sizeof(VirtAllocRec));
     77    if(!rec) {
     78        DebugInt3();
     79        return;
     80    }
     81    rec->baseaddr = baseaddr;
     82    rec->size     = size;
     83    rec->attr     = attr;
     84
     85    DosEnterCriticalSection(&alloccritsect);
     86    if(!allocrecords || allocrecords->baseaddr > baseaddr) {
     87        rec->next     = allocrecords;
     88        allocrecords  = rec;
     89    }
     90    else {
     91        tmp = allocrecords;
     92        while(tmp->next) {
     93            if(tmp->next->baseaddr > baseaddr) {     
     94                break;
     95            }
     96            tmp = tmp->next;
     97        }
     98
     99        rec->next = tmp->next;
     100        tmp->next = rec;
     101    }
     102    DosLeaveCriticalSection(&alloccritsect);
     103}
     104//******************************************************************************
     105//******************************************************************************
     106void FreeAllocRec(ULONG baseaddr)
     107{
     108    VirtAllocRec *rec = NULL, *tmp;
     109
     110    if(!allocrecords) {
     111        DebugInt3();
     112        return;
     113    }
     114
     115    DosEnterCriticalSection(&alloccritsect);
     116    if(allocrecords->baseaddr == baseaddr) {
     117        rec          = allocrecords;
     118        allocrecords = allocrecords->next;
     119    }
     120    else {
     121        tmp = allocrecords;
     122        while(tmp->next) {
     123            if(tmp->next->baseaddr == baseaddr) {     
     124                break;
     125            }
     126            tmp = tmp->next;
     127        }
     128        if(tmp->next) {
     129             rec = tmp->next;
     130             tmp->next = tmp->next->next;
     131        }
     132        else dprintf(("ERROR: FreeAllocRec: allocation not found!! (%x)", baseaddr));
     133    }
     134    DosLeaveCriticalSection(&alloccritsect);
     135    if(rec) free(rec);
     136}
     137//******************************************************************************
     138//******************************************************************************
     139BOOL FindAllocRec(ULONG addr, ULONG *lpBase, ULONG *lpSize, ULONG *lpAttr)
     140{
     141    VirtAllocRec *rec = NULL;
     142
     143    DosEnterCriticalSection(&alloccritsect);
     144    rec = allocrecords;
     145    while(rec) {
     146        if(rec->baseaddr <= addr && rec->baseaddr + rec->size > addr) {
     147            *lpBase = rec->baseaddr;
     148            *lpSize = rec->size;
     149            *lpAttr = rec->attr;
     150            break; //found it
     151        }
     152        if(rec->baseaddr > addr) {
     153            //sorted list, so no need to search any further
     154            rec = NULL;
     155            break;
     156        }
     157        rec = rec->next;
     158    }
     159    DosLeaveCriticalSection(&alloccritsect);
     160    return (rec != NULL);
     161}
    44162//******************************************************************************
    45163//TODO: Check if this works for code aliases...
     
    83201        pAlias += size;
    84202    }
     203    AddAllocRec((ULONG)*ppbAlias, cb, fl);
    85204    return 0;
    86205}
     
    99218        fMemFlags = 0;
    100219    }
     220   
    101221    /*
    102222     * Let's try use the extended DosAllocMem API of Win32k.sys.
     
    105225    {
    106226        rc = DosAllocMemEx(lplpMemAddr, cbSize, flFlags | fMemFlags | OBJ_ALIGN64K);
     227#ifdef RAS
     228        if (rc == NO_ERROR)
     229        {
     230            RasAddObject (rthVirtual, (ULONG)*lplpMemAddr, NULL, cbSize);
     231        }
     232#endif
    107233        if (rc != ERROR_NOT_SUPPORTED)  /* This call was stubbed until recently. */
    108234            return rc;
     
    132258            return rc;
    133259        }
     260       
     261        PVOID baseAddr = (PVOID)addr64kb; // sunlover20040613: save returned address for a possible Free on failure
     262       
    134263        dprintf(("Allocate aligned memory %x -> %x", addr64kb, (addr64kb + 0xFFFF) & ~0xFFFF));
    135264
     
    144273            if(rc) {
    145274                dprintf(("!ERROR!: DosSetMem failed with rc %d", rc));
     275                DosFreeMem (baseAddr); // sunlover20040613: Free allocated memory
    146276                return rc;
    147277            }
     
    149279    }
    150280
    151     if(!rc)
     281    if(!rc) {
    152282        *lplpMemAddr = pvMemAddr;
    153 
     283        AddAllocRec((ULONG)pvMemAddr, cbSize, flFlags);
     284        RasAddObject (rthVirtual, (ULONG)*lplpMemAddr, NULL, cbSize);
     285    }
    154286    return rc;
    155287}
     
    157289//Locate the base page of a memory allocation (the page with the PAG_BASE attribute)
    158290//******************************************************************************
    159 PVOID OSLibDosFindMemBase(LPVOID lpMemAddr)
    160 {
    161     ULONG  ulAttr, ulSize, ulAddr;
     291PVOID OSLibDosFindMemBase(LPVOID lpMemAddr, DWORD *lpAttr)
     292{
     293    ULONG  ulAttr, ulSize, ulAddr, ulBase;
    162294    APIRET rc;
     295    VirtAllocRec *allocrec;
     296
     297    *lpAttr = 0;
    163298   
     299    if(FindAllocRec((ULONG)lpMemAddr, &ulBase, &ulSize, lpAttr) == TRUE) {
     300        return (PVOID)ulBase;
     301    }
     302   
     303    ulSize = PAGE_SIZE;
    164304    rc = DosQueryMem(lpMemAddr, &ulSize, &ulAttr);
    165305    if(rc != NO_ERROR) {
     
    226366        dprintf(("!ERROR!: OSLibDosFreeMem: Unable to find base of %x", lpMemAddr));
    227367        DebugInt3();
    228     }
    229     else {
    230         lpMemAddr = (PVOID)ulAddr;
    231     }
    232     return DosFreeMem(lpMemAddr);
     368        return ERROR_INVALID_PARAMETER;
     369    }
     370    FreeAllocRec((ULONG)lpMemAddr);
     371   
     372    RasRemoveObject (rthVirtual, (ULONG)lpMemAddr);
     373
     374    return DosFreeMem((PVOID)ulAddr);
    233375}
    234376//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.