⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 virtmem.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                LockPages (pvAddr, 1, 0, flLock)) // TODO: We should not call this here if VAcs is already hold!!!! Change this (to fail directly or update page table directly if possible)
            { // Query only, do not lock
                pvRet = VerifyAccess (pvAddr, flVerify, (ACCESSKEY)-1);
            }
        }
        else
        { // Forced Page-in inactive (less intrusive debugger):
            fPageInFailed = TRUE;
            DEBUGMSG(ZONE_VIRTMEM, (TEXT(" DebugVerify: VMPage not paged in.\r\n")));
        }
    }

    if (pfPageInFailed) *pfPageInFailed = fPageInFailed;
    return pvRet;
}


#if HARDWARE_PT_PER_PROC

ERRFALSE(PAGE_SIZE == 4096);

MEMBLOCK *GetKPagePMB (DWORD dwVMBase)
{
    MEMBLOCK *pmb = MDAllocMemBlock (dwVMBase, 0);
    if (pmb) {
        DEBUGMSG (ZONE_VIRTMEM, (L"pmb = %8.8lx, pmb->aPages = %8.8lx\r\n", pmb, pmb->aPages));
        pmb->alk = ~0ul;
        pmb->cLocks = 1;
        pmb->ixBase = UNKNOWN_BASE;
        pmb->aPages[5] = KPAGE_PTE; // KPage is from 0x5000 to 0x5fff
    }
    return pmb;
}

#else
const MEMBLOCK KPageBlock = {
    ~0ul,       // alk
    0,          // cUses
    0,          // flags
    UNKNOWN_BASE,// ixBase
    0,          // hPf
    1,          // cLocks
    {
#if PAGE_SIZE == 4096
        0, 0, 0, 0, 0,
#elif PAGE_SIZE == 2048
        /* 0x0000: */ 0, 0, 0, 0,
        /* 0x2000: */ 0, 0, 0, 0,
        /* 0x4000: */ 0, 0, 0,
        /* 0x5800: (start of user visible kernel data page) */
#elif PAGE_SIZE == 1024
        /* 0x0000: */ 0, 0, 0, 0,
        /* 0x1000: */ 0, 0, 0, 0,
        /* 0x2000: */ 0, 0, 0, 0,
        /* 0x3000: */ 0, 0, 0, 0,
        /* 0x4000: */ 0, 0, 0, 0,
        /* 0x5000: */ 0, 0,
        /* 0x5800: (start of user visible kernel data page) */
#else
    #error Unsupported page size.
#endif
        KPAGE_PTE
    }
};

#define GetKPagePMB(dwVMBase)   ((MEMBLOCK*)&KPageBlock)

#endif

SECTION NKSection;


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPVOID 
InitNKSection(void) 
{
    NKSection[0] = GetKPagePMB (SECURE_VMBASE);
    DEBUGCHK (NKSection[0]);
    // save the address of NKSection in KInfo
    KInfoTable[KINX_NKSECTION] = (DWORD) &NKSection;
    
    return (LPVOID) SECURE_VMBASE;
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
VOID 
DeleteSection(
    LPVOID lpvSect
    ) 
{
    PSECTION pscn;
    DWORD dwSect = (DWORD) lpvSect;
    int ix;
    int ixScn;
    LPDWORD pPageList = NULL;
    
    DEBUGMSG(ZONE_VIRTMEM,(TEXT("DeleteSection %8.8lx\r\n"), dwSect));
    EnterCriticalSection(&VAcs);
    if ((ixScn = dwSect>>VA_SECTION) <= SECTION_MASK
            && ixScn >= RESERVED_SECTIONS
            && (pscn = SectionTable[ixScn]) != NULL_SECTION) {

        DEBUGCHK (pscn != &NKSection);

        // if this is a mapper section, clear the "filesys owned bit for this section
        if ((dwSect >= FIRST_MAPPER_ADDRESS) && (dwSect < LAST_MAPPER_ADDRESS)) {
            g_ObjStoreSlotBits &= ~ MapperSlotToBit (ixScn);
        }
       
        // For process sections, start freeing at block 1. Otherwise, this
        // should be a mapper section which starts freeing at block 0.
#if HARDWARE_PT_PER_PROC
        ix = 0;
#else
        ix = ((*pscn)[0] != &KPageBlock)? 0 : 1;
#endif
        for ( ; ix < BLOCK_MASK+1 ; ++ix) {
            if ((*pscn)[ix] != NULL_BLOCK) {
                if ((*pscn)[ix] != RESERVED_BLOCK) {
                    pPageList = DecommitPages(pscn, ix, 0, PAGES_PER_BLOCK, dwSect, TRUE, pPageList);
                    if ((*pscn)[ix] != RESERVED_BLOCK) {
                        MDFreeMemBlock ((*pscn)[ix]);
                    }
                }
            }
        }
        SectionTable[ixScn] = NULL_SECTION;
        FreeSection(pscn);
        if (ixScn < FirstFreeSection)
            FirstFreeSection = ixScn;
#if HARDWARE_PT_PER_PROC
        {
            extern void FreeHardwarePT (DWORD dwVMBase);
            FreeHardwarePT (dwSect);
        }
#endif
    } else
        DEBUGMSG(ZONE_VIRTMEM,(TEXT("DeleteSection failed.\r\n")));
    // do the zeroing of pages outside VAcs
    LeaveCriticalSection(&VAcs);
    FreePageList (pPageList);

    return;
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPVOID CreateSection (LPVOID lpvAddr, BOOL fInitKPage) 
{
    PSECTION pSect;
    uint ixSect;
    DEBUGMSG(ZONE_VIRTMEM,(TEXT("CreateSection %8.8lx\r\n"), lpvAddr));
    EnterCriticalSection(&VAcs);
    if (lpvAddr != 0) {
        if ((ixSect = (ulong)lpvAddr>>VA_SECTION) > SECTION_MASK
                || SectionTable[ixSect] != NULL_SECTION) {
            DEBUGMSG(1,(TEXT("CreateSection failed (1)\r\n")));
            lpvAddr = 0;
            goto exitCreate;
        }
    } else {
        /* scan for an available section table entry */
        // NOTE: never use slot 1
        for (;;) {
            for (ixSect = FirstFreeSection ; ixSect < MAX_PROCESSES+RESERVED_SECTIONS
                    ; ++ixSect) {
                if (SectionTable[ixSect] == NULL_SECTION)
                    goto foundSect;
            }
            if (FirstFreeSection == (RESERVED_SECTIONS+1))
                break;
            FirstFreeSection = RESERVED_SECTIONS+1;
        }
        /* no sections available */
        DEBUGMSG(1, (TEXT("CreateSection failed (2)\r\n")));
        goto exitCreate;
        /* found a free section set new first free index */
foundSect:
        FirstFreeSection = ixSect+1;
    }
    /* Allocate a section and initialize it to invalid blocks */
    if ((pSect = GetSection()) == 0) {
        DEBUGMSG(1, (TEXT("CreateSection failed (3)\r\n")));
        lpvAddr = 0;
        goto exitCreate;
    }
    ///memcpy(pSect, &NullSection, sizeof(NullSection));
    SectionTable[ixSect] = pSect;
    lpvAddr = (LPVOID)(ixSect << VA_SECTION);
    
    if (fInitKPage && !((*pSect)[0] = GetKPagePMB (ixSect << VA_SECTION))) {
        // failed to create Memblock
        DeleteSection (lpvAddr);
        lpvAddr = NULL;
    }
exitCreate:
    LeaveCriticalSection(&VAcs);
    DEBUGMSG(ZONE_VIRTMEM, (TEXT("CreateSection done: addr=%8.8lx, pSect=%8.8lx\r\n"), lpvAddr, pSect));
    return lpvAddr;
}



// CreateMapperSection - allocate memory section for file mapping
//
//  This function will allocate a 32mb section and reserve the entire range for
// use by file mapping.

DWORD g_ObjStoreSlotBits;  // bit fields

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL CreateMapperSection (DWORD dwBase, BOOL fAddProtect) 
{
    BOOL bRet = FALSE;
    MEMBLOCK *pmb;
    PSECTION pscn;
    int ix;
    DEBUGMSG(ZONE_VIRTMEM,(TEXT("CreateMapperSection %8.8lx\r\n"), dwBase));
    if (dwBase < FIRST_MAPPER_ADDRESS || dwBase >= LAST_MAPPER_ADDRESS) {
        DEBUGMSG(1, (TEXT("CreateMapperSection: %8.8lx is out of range.\r\n"), dwBase));
        return FALSE;
    }
    // First, create a normal section. Then convert it into a special section
    // for the Mapper.
    EnterCriticalSection(&VAcs);
    if (CreateSection((LPVOID)dwBase, FALSE) != 0) {
        DWORD dwSlot = (dwBase>>VA_SECTION) & SECTION_MASK;
        pscn = SectionTable[dwSlot];
        if (pmb = MDAllocMemBlock (dwBase, 0)) {
            if (fAddProtect) {
                LockFromKey(&pmb->alk, &pCurProc->aky);
                // 2nd gig section with protection, it's object store
                g_ObjStoreSlotBits |= MapperSlotToBit (dwSlot);
            } else
                LockFromKey(&pmb->alk, &ProcArray[0].aky);
            pmb->cUses = 1;
            pmb->flags = MB_PAGER_MAPPING;
            pmb->ixBase = 0;
            (*pscn)[0] = pmb;
            for (ix = 1 ; ix < BLOCK_MASK+1 ; ++ix)
                (*pscn)[ix] = RESERVED_BLOCK;
            bRet = TRUE;
        } else {
            DeleteSection((LPVOID)dwBase);
            DEBUGMSG(1, (TEXT("CreateMapperSection: unable to allocate MEMBLOCK\r\n")));
        }
    }
    LeaveCriticalSection(&VAcs);
    return bRet;
}



//------------------------------------------------------------------------------
// DeleteMapperSection - delete a section created by CreateMapperSection()
//
//  This function must be used to delete a memory section which is created by
// CreateMapperSection.
//------------------------------------------------------------------------------
void 
DeleteMapperSection(
    DWORD dwBase
    ) 
{
    if ((dwBase >= FIRST_MAPPER_ADDRESS) && (dwBase < LAST_MAPPER_ADDRESS))
        DeleteSection((LPVOID)dwBase);
    else 
        DEBUGMSG(1, (TEXT("DeleteMapperSection: %8.8lx is out of range.\r\n"), dwBase));
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPVOID 
DoVirtualAlloc(
    LPVOID lpvAddress0,          /* address of region to reserve or commit */
    DWORD cbSize,               /* size of the region */
    DWORD fdwAllocationType,    /* type of allocation */
    DWORD fdwProtect,           /* type of access protection */
    DWORD fdwInternal,
    DWORD dwPFNBase
    )
{
    int ixBlock;
    int ixPage;
    int ix;
    int ixFirB;                 /* index of first block in region */
    PSECTION pscn;
    int cPages;                 /* # of pages to allocate */
    int cNeed;
    int cpAlloc;                /* # of physical pages to allocate */
    ulong ulPgMask;             /* page permissions */
    ulong ulPFN;                /* page physical frame number */
    MEMBLOCK *pmb;
    DWORD err;
    DWORD dwEnd;
    LPVOID lpvResult = NULL;
    DWORD dwAddr = (DWORD) lpvAddress0;
    DWORD dwSlot0Addr = ZeroPtrABS(dwAddr);
    ACCESSKEY aky = pCurProc->aky;
    DWORD dwBase;
    BOOL  fNeedInvalidate = FALSE;
    
    ixFirB = UNKNOWN_BASE;

    DEBUGMSG(ZONE_VIRTMEM, (TEXT("VirtualAlloc(%8.8lx, %lx, %lx, %lx)\r\n"),
            lpvAddress0, cbSize, fdwAllocationType, fdwProtect));


    // validate parameters
    if (IsKernelVa (dwAddr)          // invalid address?
        || !cbSize                   // size == 0?
        || ((cbSize >= (1<<VA_SECTION)) // size too big? (okay to reserver > 32M with specific parameters)
            && (dwSlot0Addr || (fdwAllocationType != MEM_RESERVE) || (fdwProtect != PAGE_NOACCESS)))
        || !(ulPgMask = MakePagePerms(fdwProtect, dwAddr))) {   // invalid flag?
        KSetLastError(pCurThread, ERROR_INVALID_PARAMETER);
        return NULL;
    }        

    dwEnd = dwAddr + cbSize;

    //    
    // Lockout other changes to the virtual memory state. 
    //
    EnterCriticalSection(&VAcs);
    
    if (IsSecureVa(dwAddr)) {
        aky = ProcArray[0].aky;
        pscn = &NKSection;
        dwBase = SECURE_VMBASE;
    } else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -