ldrFile.cpp revision c98fb3e16fcd571a790eab772c0c66173d225205
cf25f919d659bf00f73e1551230cd6165961061dvboxsync/* $Id$ */
cf25f919d659bf00f73e1551230cd6165961061dvboxsync/** @file
cf25f919d659bf00f73e1551230cd6165961061dvboxsync * innotek Portable Runtime - Binary Image Loader, The File Oriented Parts.
cf25f919d659bf00f73e1551230cd6165961061dvboxsync */
cf25f919d659bf00f73e1551230cd6165961061dvboxsync
cf25f919d659bf00f73e1551230cd6165961061dvboxsync/*
cf25f919d659bf00f73e1551230cd6165961061dvboxsync * Copyright (C) 2006-2007 innotek GmbH
cf25f919d659bf00f73e1551230cd6165961061dvboxsync *
cf25f919d659bf00f73e1551230cd6165961061dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
cf25f919d659bf00f73e1551230cd6165961061dvboxsync * available from http://www.virtualbox.org. This file is free software;
cf25f919d659bf00f73e1551230cd6165961061dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
cf25f919d659bf00f73e1551230cd6165961061dvboxsync * General Public License as published by the Free Software Foundation,
cf25f919d659bf00f73e1551230cd6165961061dvboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
cf25f919d659bf00f73e1551230cd6165961061dvboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
cf25f919d659bf00f73e1551230cd6165961061dvboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
cf25f919d659bf00f73e1551230cd6165961061dvboxsync */
cf25f919d659bf00f73e1551230cd6165961061dvboxsync
cf25f919d659bf00f73e1551230cd6165961061dvboxsync/*******************************************************************************
cf25f919d659bf00f73e1551230cd6165961061dvboxsync* Header Files *
cf25f919d659bf00f73e1551230cd6165961061dvboxsync*******************************************************************************/
cf25f919d659bf00f73e1551230cd6165961061dvboxsync#define LOG_GROUP RTLOGGROUP_LDR
cf25f919d659bf00f73e1551230cd6165961061dvboxsync#include <iprt/ldr.h>
cf25f919d659bf00f73e1551230cd6165961061dvboxsync#include <iprt/alloc.h>
cf25f919d659bf00f73e1551230cd6165961061dvboxsync#include <iprt/file.h>
cf25f919d659bf00f73e1551230cd6165961061dvboxsync#include <iprt/assert.h>
cf25f919d659bf00f73e1551230cd6165961061dvboxsync#include <iprt/log.h>
cf25f919d659bf00f73e1551230cd6165961061dvboxsync#include <iprt/err.h>
cf25f919d659bf00f73e1551230cd6165961061dvboxsync#include <iprt/string.h>
cf25f919d659bf00f73e1551230cd6165961061dvboxsync#include "internal/ldr.h"
cf25f919d659bf00f73e1551230cd6165961061dvboxsync#include "internal/ldrMZ.h"
cf25f919d659bf00f73e1551230cd6165961061dvboxsync
cf25f919d659bf00f73e1551230cd6165961061dvboxsync
cf25f919d659bf00f73e1551230cd6165961061dvboxsync/*******************************************************************************
cf25f919d659bf00f73e1551230cd6165961061dvboxsync* Structures and Typedefs *
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync*******************************************************************************/
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync/**
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync * File Reader instance.
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync * This provides raw image bits from a file.
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync */
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsynctypedef struct RTLDRREADERFILE
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync{
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync /** The core. */
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync RTLDRREADER Core;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync /** The file. */
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync RTFILE File;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync /** The file size. */
cf25f919d659bf00f73e1551230cd6165961061dvboxsync RTFOFF cbFile;
cf25f919d659bf00f73e1551230cd6165961061dvboxsync /** The current offset. */
cf25f919d659bf00f73e1551230cd6165961061dvboxsync RTFOFF off;
cf25f919d659bf00f73e1551230cd6165961061dvboxsync /** Number of users or the mapping. */
cf25f919d659bf00f73e1551230cd6165961061dvboxsync RTUINT cMappings;
cf25f919d659bf00f73e1551230cd6165961061dvboxsync /** Pointer to the in memory mapping. */
cf25f919d659bf00f73e1551230cd6165961061dvboxsync void *pvMapping;
cf25f919d659bf00f73e1551230cd6165961061dvboxsync /** The filename (variable size). */
cf25f919d659bf00f73e1551230cd6165961061dvboxsync char szFilename[1];
cf25f919d659bf00f73e1551230cd6165961061dvboxsync} RTLDRREADERFILE, *PRTLDRREADERFILE;
cf25f919d659bf00f73e1551230cd6165961061dvboxsync
cf25f919d659bf00f73e1551230cd6165961061dvboxsync
cf25f919d659bf00f73e1551230cd6165961061dvboxsync/** @copydoc RTLDRREADER::pfnRead */
cf25f919d659bf00f73e1551230cd6165961061dvboxsyncstatic DECLCALLBACK(int) rtldrFileRead(PRTLDRREADER pReader, void *pvBuf, size_t cb, RTFOFF off)
cf25f919d659bf00f73e1551230cd6165961061dvboxsync{
cf25f919d659bf00f73e1551230cd6165961061dvboxsync PRTLDRREADERFILE pFileReader = (PRTLDRREADERFILE)pReader;
cf25f919d659bf00f73e1551230cd6165961061dvboxsync
cf25f919d659bf00f73e1551230cd6165961061dvboxsync /*
cf25f919d659bf00f73e1551230cd6165961061dvboxsync * Seek.
cf25f919d659bf00f73e1551230cd6165961061dvboxsync */
cf25f919d659bf00f73e1551230cd6165961061dvboxsync if (pFileReader->off != off)
cf25f919d659bf00f73e1551230cd6165961061dvboxsync {
cf25f919d659bf00f73e1551230cd6165961061dvboxsync int rc = RTFileSeek(pFileReader->File, off, RTFILE_SEEK_BEGIN, NULL);
cf25f919d659bf00f73e1551230cd6165961061dvboxsync if (RT_FAILURE(rc))
cf25f919d659bf00f73e1551230cd6165961061dvboxsync {
cf25f919d659bf00f73e1551230cd6165961061dvboxsync pFileReader->off = -1;
cf25f919d659bf00f73e1551230cd6165961061dvboxsync return rc;
cf25f919d659bf00f73e1551230cd6165961061dvboxsync }
cf25f919d659bf00f73e1551230cd6165961061dvboxsync pFileReader->off = off;
cf25f919d659bf00f73e1551230cd6165961061dvboxsync }
cf25f919d659bf00f73e1551230cd6165961061dvboxsync
cf25f919d659bf00f73e1551230cd6165961061dvboxsync /*
cf25f919d659bf00f73e1551230cd6165961061dvboxsync * Read.
cf25f919d659bf00f73e1551230cd6165961061dvboxsync */
cf25f919d659bf00f73e1551230cd6165961061dvboxsync int rc = RTFileRead(pFileReader->File, pvBuf, cb, NULL);
cf25f919d659bf00f73e1551230cd6165961061dvboxsync if (RT_SUCCESS(rc))
cf25f919d659bf00f73e1551230cd6165961061dvboxsync pFileReader->off += cb;
cf25f919d659bf00f73e1551230cd6165961061dvboxsync else
cf25f919d659bf00f73e1551230cd6165961061dvboxsync pFileReader->off = -1;
cf25f919d659bf00f73e1551230cd6165961061dvboxsync return rc;
cf25f919d659bf00f73e1551230cd6165961061dvboxsync}
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync/** @copydoc RTLDRREADER::pfnTell */
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsyncstatic DECLCALLBACK(RTFOFF) rtldrFileTell(PRTLDRREADER pReader)
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync{
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync PRTLDRREADERFILE pFileReader = (PRTLDRREADERFILE)pReader;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync return pFileReader->off;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync}
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync/** @copydoc RTLDRREADER::pfnSize */
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsyncstatic DECLCALLBACK(RTFOFF) rtldrFileSize(PRTLDRREADER pReader)
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync{
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync PRTLDRREADERFILE pFileReader = (PRTLDRREADERFILE)pReader;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync return pFileReader->cbFile;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync}
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync/** @copydoc RTLDRREADER::pfnLogName */
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsyncstatic DECLCALLBACK(const char *) rtldrFileLogName(PRTLDRREADER pReader)
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync{
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync PRTLDRREADERFILE pFileReader = (PRTLDRREADERFILE)pReader;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync return pFileReader->szFilename;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync}
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync/** @copydoc RTLDRREADER::pfnFileMap */
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsyncstatic DECLCALLBACK(int) rtldrFileMap(PRTLDRREADER pReader, const void **ppvBits)
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync{
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync PRTLDRREADERFILE pFileReader = (PRTLDRREADERFILE)pReader;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync /*
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync * Already mapped?
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync */
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync if (pFileReader->pvMapping)
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync {
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->cMappings++;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync *ppvBits = pFileReader->pvMapping;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync return VINF_SUCCESS;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync }
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync /*
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync * Allocate memory.
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync */
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync size_t cb = (size_t)pFileReader->cbFile;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync if ((RTFOFF)cb != pFileReader->cbFile)
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync return VERR_IMAGE_TOO_BIG;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->pvMapping = RTMemAlloc(cb);
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync if (!pFileReader->pvMapping)
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync return VERR_NO_MEMORY;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync int rc = rtldrFileRead(pReader, pFileReader->pvMapping, cb, 0);
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync if (RT_SUCCESS(rc))
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync {
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->cMappings = 1;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync *ppvBits = pFileReader->pvMapping;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync }
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync else
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync {
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync RTMemFree(pFileReader->pvMapping);
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->pvMapping = NULL;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync }
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync return rc;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync}
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync/** @copydoc RTLDRREADER::pfnUnmap */
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsyncstatic DECLCALLBACK(int) rtldrFileUnmap(PRTLDRREADER pReader, const void *pvBits)
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync{
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync PRTLDRREADERFILE pFileReader = (PRTLDRREADERFILE)pReader;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync AssertReturn(pFileReader->cMappings > 0, VERR_INVALID_PARAMETER);
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync if (!--pFileReader->cMappings)
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync {
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync RTMemFree(pFileReader->pvMapping);
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->pvMapping = NULL;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync }
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync return VINF_SUCCESS;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync}
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync/** @copydoc RTLDRREADER::pfnDestroy */
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsyncstatic DECLCALLBACK(int) rtldrFileDestroy(PRTLDRREADER pReader)
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync{
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync int rc = VINF_SUCCESS;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync PRTLDRREADERFILE pFileReader = (PRTLDRREADERFILE)pReader;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync if (pFileReader->File != NIL_RTFILE)
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync {
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync rc = RTFileClose(pFileReader->File);
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync AssertRC(rc);
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->File = NIL_RTFILE;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync }
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync RTMemFree(pFileReader);
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync return rc;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync}
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync/**
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync * Opens a loader file reader.
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync *
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync * @returns iprt status code.
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync * @param ppReader Where to store the reader instance on success.
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync * @param pszFilename The file to open.
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync */
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsyncstatic int rtldrFileCreate(PRTLDRREADER *ppReader, const char *pszFilename)
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync{
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync size_t cchFilename = strlen(pszFilename);
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync int rc = VERR_NO_MEMORY;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync PRTLDRREADERFILE pFileReader = (PRTLDRREADERFILE)RTMemAlloc(sizeof(*pFileReader) + cchFilename);
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync if (pFileReader)
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync {
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync memcpy(pFileReader->szFilename, pszFilename, cchFilename + 1);
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync rc = RTFileOpen(&pFileReader->File, pszFilename, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync if (RT_SUCCESS(rc))
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync {
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync rc = RTFileGetSize(pFileReader->File, (uint64_t *)&pFileReader->cbFile);
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync if (RT_SUCCESS(rc))
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync {
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->Core.pfnRead = rtldrFileRead;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->Core.pfnTell = rtldrFileTell;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->Core.pfnSize = rtldrFileSize;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->Core.pfnLogName = rtldrFileLogName;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->Core.pfnMap = rtldrFileMap;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->Core.pfnUnmap = rtldrFileUnmap;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->Core.pfnDestroy = rtldrFileDestroy;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->off = 0;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->cMappings = 0;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync pFileReader->pvMapping = NULL;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync *ppReader = &pFileReader->Core;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync return VINF_SUCCESS;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync }
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync RTFileClose(pFileReader->File);
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync }
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync RTMemFree(pFileReader);
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync }
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync *ppReader = NULL;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync return rc;
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync}
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync/**
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync * Open a binary image file.
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync *
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync * @returns iprt status code.
a0cebf7fbe7defe88df7dcb64e51af63480b7ab0vboxsync * @param pszFilename Image filename.
cf25f919d659bf00f73e1551230cd6165961061dvboxsync * @param phLdrMod Where to store the handle to the loaded module.
cf25f919d659bf00f73e1551230cd6165961061dvboxsync */
RTDECL(int) RTLdrOpen(const char *pszFilename, PRTLDRMOD phLdrMod)
{
LogFlow(("RTLdrOpen: pszFilename=%p:{%s} phLdrMod=%p\n",
pszFilename, pszFilename, phLdrMod));
/*
* Create file reader & invoke worker which identifies and calls the image interpreter.
*/
PRTLDRREADER pReader;
int rc = rtldrFileCreate(&pReader, pszFilename);
if (RT_SUCCESS(rc))
{
rc = rtldrOpenWithReader(pReader, phLdrMod);
if (RT_SUCCESS(rc))
{
LogFlow(("RTLdrOpen: return %Rrc *phLdrMod\n", rc, *phLdrMod));
return rc;
}
pReader->pfnDestroy(pReader);
}
*phLdrMod = NIL_RTLDRMOD;
LogFlow(("RTLdrOpen: return %Rrc\n", rc));
return rc;
}
/**
* Opens a binary image file using kLdr.
*
* @returns iprt status code.
* @param pszFilename Image filename.
* @param phLdrMod Where to store the handle to the loaded module.
* @remark Primarily for testing the loader.
*/
RTDECL(int) RTLdrOpenkLdr(const char *pszFilename, PRTLDRMOD phLdrMod)
{
#ifdef LDR_WITH_KLDR
LogFlow(("RTLdrOpenkLdr: pszFilename=%p:{%s} phLdrMod=%p\n",
pszFilename, pszFilename, phLdrMod));
/*
* Create file reader & invoke worker which identifies and calls the image interpreter.
*/
PRTLDRREADER pReader;
int rc = rtldrFileCreate(&pReader, pszFilename);
if (RT_SUCCESS(rc))
{
rc = rtldrkLdrOpen(pReader, phLdrMod);
if (RT_SUCCESS(rc))
{
LogFlow(("RTLdrOpenkLdr: return %Rrc *phLdrMod\n", rc, *phLdrMod));
return rc;
}
pReader->pfnDestroy(pReader);
}
*phLdrMod = NIL_RTLDRMOD;
LogFlow(("RTLdrOpenkLdr: return %Rrc\n", rc));
return rc;
#else
return RTLdrOpen(pszFilename, phLdrMod);
#endif
}