VirtualBox

Changeset 74254 in vbox for trunk/src/VBox/Runtime/r3/darwin


Ignore:
Timestamp:
Sep 13, 2018 5:22:07 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
125048
Message:

IPRT/krnlmod-darwin: Load and resolve IOKit dependency manually as it is not present on older OS x versions. bugref:9152

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/darwin/krnlmod-darwin.cpp

    r68675 r74254  
    3131#define LOG_GROUP RTLOGGROUP_SYSTEM
    3232#include <iprt/krnlmod.h>
     33
    3334#include <iprt/asm.h>
    3435#include <iprt/assert.h>
    3536#include <iprt/err.h>
     37#include <iprt/ldr.h>
    3638#include <iprt/mem.h>
     39#include <iprt/once.h>
    3740#include <iprt/string.h>
    3841#include <iprt/types.h>
     
    4144#include <IOKit/IOKitLib.h>
    4245
     46
     47/** @name Missing/private IOKitLib declarations and definitions.
     48 * @{  */
     49/** OSKextCopyLoadedKextInfo in IOKit. */
     50typedef CFDictionaryRef (* PFNOSKEXTCOPYLOADEDKEXTINFO)(CFArrayRef, CFArrayRef);
     51
     52#ifndef kOSBundleRetainCountKey
     53# define kOSBundleRetainCountKey CFSTR("OSBundleRetainCount")
     54#endif
     55#ifndef kOSBundleLoadSizeKey
     56# define kOSBundleLoadSizeKey CFSTR("OSBundleLoadSize")
     57#endif
     58#ifndef kOSBundleLoadAddressKey
     59# define kOSBundleLoadAddressKey CFSTR("OSBundleLoadAddress")
     60#endif
     61/** @} */
     62
     63
     64/*********************************************************************************************************************************
     65*   Structures and Typedefs                                                                                                      *
     66*********************************************************************************************************************************/
    4367/**
    4468 * Internal kernel information record state.
     
    5680typedef const RTKRNLMODINFOINT *PCRTKRNLMODINFOINT;
    5781
    58 /**
    59  * The declarations are not exposed so we have to define them ourselves.
    60  */
    61 extern "C"
    62 {
    63     extern CFDictionaryRef OSKextCopyLoadedKextInfo(CFArrayRef, CFArrayRef);
    64 }
    65 
    66 #ifndef kOSBundleRetainCountKey
    67 # define kOSBundleRetainCountKey CFSTR("OSBundleRetainCount")
    68 #endif
    69 
    70 #ifndef kOSBundleLoadSizeKey
    71 # define kOSBundleLoadSizeKey CFSTR("OSBundleLoadSize")
    72 #endif
    73 
    74 #ifndef kOSBundleLoadAddressKey
    75 # define kOSBundleLoadAddressKey CFSTR("OSBundleLoadAddress")
    76 #endif
     82
     83/*********************************************************************************************************************************
     84*   Global Variables                                                                                                             *
     85*********************************************************************************************************************************/
     86static RTONCE                       g_GetIoKitApisOnce = RTONCE_INITIALIZER;
     87static PFNOSKEXTCOPYLOADEDKEXTINFO  g_pfnOSKextCopyLoadedKextInfo = NULL;
     88
     89/** Do-once callback for setting g_pfnOSKextCopyLoadedKextInfo.   */
     90static DECLCALLBACK(int) rtKrnlModDarwinResolveIoKitApis(void *pvUser)
     91{
     92    RTLDRMOD hMod;
     93//    int rc = RTLdrLoad("/System/Library/Frameworks/IOKit.framework/Versions/Current/IOKit", &hMod);
     94    int rc = RTLdrLoadEx("/System/Library/Frameworks/IOKit.framework/Versions/Current/IOKit", &hMod, RTLDRLOAD_FLAGS_NO_SUFFIX, NULL);
     95    if (RT_SUCCESS(rc))
     96        RTLdrGetSymbol(hMod, "OSKextCopyLoadedKextInfo",  (void **)&g_pfnOSKextCopyLoadedKextInfo);
     97
     98    RT_NOREF(pvUser);
     99    return VINF_SUCCESS;
     100}
    77101
    78102/**
     
    85109{
    86110    CFDictionaryRef hDictKext = NULL;
    87     CFStringRef hKextName = CFStringCreateWithCString(kCFAllocatorDefault, pszName, kCFStringEncodingUTF8);
    88     if (hKextName)
    89     {
    90         CFArrayRef hArrKextIdRef = CFArrayCreate(kCFAllocatorDefault, (const void **)&hKextName, 1, &kCFTypeArrayCallBacks);
    91         if (hArrKextIdRef)
     111
     112    RTOnce(&g_GetIoKitApisOnce, rtKrnlModDarwinResolveIoKitApis, NULL);
     113    if (g_pfnOSKextCopyLoadedKextInfo)
     114    {
     115        CFStringRef hKextName = CFStringCreateWithCString(kCFAllocatorDefault, pszName, kCFStringEncodingUTF8);
     116        if (hKextName)
    92117        {
    93             CFDictionaryRef hLoadedKexts = OSKextCopyLoadedKextInfo(hArrKextIdRef, NULL /* all info */);
    94             if (hLoadedKexts)
     118            CFArrayRef hArrKextIdRef = CFArrayCreate(kCFAllocatorDefault, (const void **)&hKextName, 1, &kCFTypeArrayCallBacks);
     119            if (hArrKextIdRef)
    95120            {
    96                 if (CFDictionaryGetCount(hLoadedKexts) > 0)
     121                CFDictionaryRef hLoadedKexts = g_pfnOSKextCopyLoadedKextInfo(hArrKextIdRef, NULL /* all info */);
     122                if (hLoadedKexts)
    97123                {
    98                     hDictKext = (CFDictionaryRef)CFDictionaryGetValue(hLoadedKexts, hKextName);
    99                     CFRetain(hDictKext);
     124                    if (CFDictionaryGetCount(hLoadedKexts) > 0)
     125                    {
     126                        hDictKext = (CFDictionaryRef)CFDictionaryGetValue(hLoadedKexts, hKextName);
     127                        CFRetain(hDictKext);
     128                    }
     129
     130                    CFRelease(hLoadedKexts);
    100131                }
    101 
    102                 CFRelease(hLoadedKexts);
     132                CFRelease(hArrKextIdRef);
    103133            }
    104             CFRelease(hArrKextIdRef);
     134            CFRelease(hKextName);
    105135        }
    106         CFRelease(hKextName);
    107136    }
    108137
     
    167196{
    168197    uint32_t cLoadedKexts = 0;
    169     CFDictionaryRef hLoadedKexts = OSKextCopyLoadedKextInfo(NULL, NULL /* all info */);
    170     if (hLoadedKexts)
    171     {
    172         cLoadedKexts = CFDictionaryGetCount(hLoadedKexts);
    173         CFRelease(hLoadedKexts);
     198    RTOnce(&g_GetIoKitApisOnce, rtKrnlModDarwinResolveIoKitApis, NULL);
     199    if (g_pfnOSKextCopyLoadedKextInfo)
     200    {
     201        CFDictionaryRef hLoadedKexts = g_pfnOSKextCopyLoadedKextInfo(NULL, NULL /* all info */);
     202        if (hLoadedKexts)
     203        {
     204            cLoadedKexts = CFDictionaryGetCount(hLoadedKexts);
     205            CFRelease(hLoadedKexts);
     206        }
    174207    }
    175208
     
    184217
    185218    int rc = VINF_SUCCESS;
    186     CFDictionaryRef hLoadedKexts = OSKextCopyLoadedKextInfo(NULL, NULL /* all info */);
    187     if (hLoadedKexts)
    188     {
    189         uint32_t cLoadedKexts = CFDictionaryGetCount(hLoadedKexts);
    190         if (cLoadedKexts <= cEntriesMax)
     219    RTOnce(&g_GetIoKitApisOnce, rtKrnlModDarwinResolveIoKitApis, NULL);
     220    if (g_pfnOSKextCopyLoadedKextInfo)
     221    {
     222        CFDictionaryRef hLoadedKexts = g_pfnOSKextCopyLoadedKextInfo(NULL, NULL /* all info */);
     223        if (hLoadedKexts)
    191224        {
    192             CFDictionaryRef *pahDictKext = (CFDictionaryRef *)RTMemTmpAllocZ(cLoadedKexts * sizeof(CFDictionaryRef));
    193             if (pahDictKext)
     225            uint32_t cLoadedKexts = CFDictionaryGetCount(hLoadedKexts);
     226            if (cLoadedKexts <= cEntriesMax)
    194227            {
    195                 CFDictionaryGetKeysAndValues(hLoadedKexts, NULL, (const void **)pahDictKext);
    196                 for (uint32_t i = 0; i < cLoadedKexts; i++)
     228                CFDictionaryRef *pahDictKext = (CFDictionaryRef *)RTMemTmpAllocZ(cLoadedKexts * sizeof(CFDictionaryRef));
     229                if (pahDictKext)
    197230                {
    198                     PRTKRNLMODINFOINT pThis = (PRTKRNLMODINFOINT)RTMemAllocZ(sizeof(RTKRNLMODINFOINT));
    199                     if (RT_LIKELY(pThis))
     231                    CFDictionaryGetKeysAndValues(hLoadedKexts, NULL, (const void **)pahDictKext);
     232                    for (uint32_t i = 0; i < cLoadedKexts; i++)
    200233                    {
    201                         pThis->cRefs = 1;
    202                         pThis->hDictKext = pahDictKext[i];
    203                         CFRetain(pThis->hDictKext);
    204                         pahKrnlModInfo[i] = pThis;
    205                     }
    206                     else
    207                     {
    208                         rc = VERR_NO_MEMORY;
    209                         /* Rollback. */
    210                         while (i-- > 0)
     234                        PRTKRNLMODINFOINT pThis = (PRTKRNLMODINFOINT)RTMemAllocZ(sizeof(RTKRNLMODINFOINT));
     235                        if (RT_LIKELY(pThis))
    211236                        {
    212                             CFRelease(pahKrnlModInfo[i]->hDictKext);
    213                             RTMemFree(pahKrnlModInfo[i]);
     237                            pThis->cRefs = 1;
     238                            pThis->hDictKext = pahDictKext[i];
     239                            CFRetain(pThis->hDictKext);
     240                            pahKrnlModInfo[i] = pThis;
     241                        }
     242                        else
     243                        {
     244                            rc = VERR_NO_MEMORY;
     245                            /* Rollback. */
     246                            while (i-- > 0)
     247                            {
     248                                CFRelease(pahKrnlModInfo[i]->hDictKext);
     249                                RTMemFree(pahKrnlModInfo[i]);
     250                            }
    214251                        }
    215252                    }
     253
     254                    if (   RT_SUCCESS(rc)
     255                        && pcEntries)
     256                        *pcEntries = cLoadedKexts;
     257
     258                    RTMemTmpFree(pahDictKext);
    216259                }
    217 
    218                 if (   RT_SUCCESS(rc)
    219                     && pcEntries)
    220                     *pcEntries = cLoadedKexts;
    221 
    222                 RTMemTmpFree(pahDictKext);
     260                else
     261                    rc = VERR_NO_MEMORY;
    223262            }
    224263            else
    225                 rc = VERR_NO_MEMORY;
     264            {
     265                rc = VERR_BUFFER_OVERFLOW;
     266
     267                if (pcEntries)
     268                    *pcEntries = cLoadedKexts;
     269            }
     270
     271            CFRelease(hLoadedKexts);
    226272        }
    227273        else
    228         {
    229             rc = VERR_BUFFER_OVERFLOW;
    230 
    231             if (pcEntries)
    232                 *pcEntries = cLoadedKexts;
    233         }
    234 
    235         CFRelease(hLoadedKexts);
     274            rc = VERR_NOT_SUPPORTED;
    236275    }
    237276    else
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette