Logo Search packages:      
Sourcecode: virtualbox-ose version File versions

int kLdrModOpenFromRdr ( PKRDR  pRdr,
PPKLDRMOD  ppMod 
)

Open a executable image from a file provider instance.

Returns:
0 on success and *ppMod pointing to a module instance. On failure, a non-zero OS specific error code is returned.
Parameters:
pRdr The file provider instance to use. On success, the ownership of the instance is taken by the module and the caller must not ever touch it again. (The instance is not closed on failure, the call has to do that.)
ppMod Where to store the module handle.

Definition at line 143 of file kLdrMod.c.

References g_kLdrModLXOps, g_kLdrModMachOOps, g_kLdrModPEOps, IMAGE_DOS_SIGNATURE, IMAGE_ELF_SIGNATURE, IMAGE_FAT_SIGNATURE, IMAGE_FAT_SIGNATURE_OE, IMAGE_LE_SIGNATURE, IMAGE_LX_SIGNATURE, IMAGE_MACHO32_SIGNATURE, IMAGE_MACHO32_SIGNATURE_OE, IMAGE_MACHO64_SIGNATURE, IMAGE_MACHO64_SIGNATURE_OE, IMAGE_NE_SIGNATURE, IMAGE_NT_SIGNATURE, K_OFFSETOF, KLDR_ERR_ELF_NOT_SUPPORTED, KLDR_ERR_FAT_NOT_SUPPORTED, KLDR_ERR_LE_NOT_SUPPORTED, KLDR_ERR_MZ_NOT_SUPPORTED, KLDR_ERR_NE_NOT_SUPPORTED, KLDR_ERR_UNKNOWN_FORMAT, NULL, KLDRMODOPS::pfnCreate, and KLDRMODOPS::pNext.

Referenced by kldrDyldModCreate(), and kLdrModOpen().

{
    union
    {
        KU32        u32;
        KU16        u16;
        KU16        au16[2];
        KU8         au8[4];
    }           u;
    KLDRFOFF    offHdr = 0;
    int         rc;

    /*
     * Try figure out what kind of image this is.
     * Always read the 'new header' if we encounter MZ.
     */
    rc = kRdrRead(pRdr, &u, sizeof(u), 0);
    if (rc)
        return rc;
    if (    u.u16 == IMAGE_DOS_SIGNATURE
        &&  kRdrSize(pRdr) > sizeof(IMAGE_DOS_HEADER))
    {
        rc = kRdrRead(pRdr, &u, sizeof(u.u32), K_OFFSETOF(IMAGE_DOS_HEADER, e_lfanew));
        if (rc)
            return rc;
        if ((KLDRFOFF)u.u32 < kRdrSize(pRdr))
        {
            offHdr = u.u32;
            rc = kRdrRead(pRdr, &u, sizeof(u.u32), offHdr);
            if (rc)
                return rc;
        }
        else
            u.u16 = IMAGE_DOS_SIGNATURE;
    }

    /*
     * Use the magic to select the appropriate image interpreter head on.
     */
    if (u.u16 == IMAGE_DOS_SIGNATURE)
        rc = KLDR_ERR_MZ_NOT_SUPPORTED;
    else if (u.u16 == IMAGE_NE_SIGNATURE)
        rc = KLDR_ERR_NE_NOT_SUPPORTED;
    else if (u.u16 == IMAGE_LX_SIGNATURE)
        rc = g_kLdrModLXOps.pfnCreate(&g_kLdrModLXOps, pRdr, offHdr, ppMod);
    else if (u.u16 == IMAGE_LE_SIGNATURE)
        rc = KLDR_ERR_LE_NOT_SUPPORTED;
    else if (u.u32 == IMAGE_NT_SIGNATURE)
        rc = g_kLdrModPEOps.pfnCreate(&g_kLdrModPEOps, pRdr, offHdr, ppMod);
    else if (   u.u32 == IMAGE_MACHO32_SIGNATURE
             || u.u32 == IMAGE_MACHO32_SIGNATURE_OE
             || u.u32 == IMAGE_MACHO64_SIGNATURE
             || u.u32 == IMAGE_MACHO64_SIGNATURE_OE)
        rc = g_kLdrModMachOOps.pfnCreate(&g_kLdrModMachOOps, pRdr, offHdr, ppMod);
    else if (u.u32 == IMAGE_ELF_SIGNATURE)
        rc = KLDR_ERR_ELF_NOT_SUPPORTED;
    else if (   u.u32 == IMAGE_FAT_SIGNATURE
             || u.u32 == IMAGE_FAT_SIGNATURE_OE)
        rc = KLDR_ERR_FAT_NOT_SUPPORTED;
    else
        rc = KLDR_ERR_UNKNOWN_FORMAT;

    /*
     * If no head on hit, let each interpreter have a go.
     */
    if (rc)
    {
        PCKLDRMODOPS pOps;
        for (pOps = g_pModInterpreterHead; pOps; pOps = pOps->pNext)
        {
            int rc2 = pOps->pfnCreate(pOps, pRdr, offHdr, ppMod);
            if (!rc2)
                return rc;
        }
        *ppMod = NULL;
    }
    return rc;
}


Generated by  Doxygen 1.6.0   Back to index