VirtualBox

Ignore:
Timestamp:
Sep 26, 2020 9:59:44 AM (4 years ago)
Author:
vboxsync
Message:

Runtime: Add API to load kernel modules by name and add simple implementation for macOS, bugref:9836

File:
1 edited

Legend:

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

    r82968 r86300  
    4343#include <CoreFoundation/CoreFoundation.h>
    4444#include <IOKit/IOKitLib.h>
     45#include <libkern/OSReturn.h>
    4546
    4647
     
    4950/** OSKextCopyLoadedKextInfo in IOKit. */
    5051typedef CFDictionaryRef (* PFNOSKEXTCOPYLOADEDKEXTINFO)(CFArrayRef, CFArrayRef);
     52/** KextManagerLoadKextWithURL in IOKit. */
     53typedef OSReturn (* PFNKEXTMANAGERLOADKEXTWITHURL)(CFURLRef, CFArrayRef);
     54/** KextManagerLoadKextWithIdentifier in IOKit */
     55typedef OSReturn (* PFNKEXTMANAGERLOADKEXTWITHIDENTIFIER)(CFStringRef, CFArrayRef);
     56/** KextManagerUnloadKextWithIdentifier in IOKit */
     57typedef OSReturn (* PFNKEXTMANAGERUNLOADKEXTWITHIDENTIFIER)(CFStringRef);
    5158
    5259#ifndef kOSBundleRetainCountKey
     
    8491*   Global Variables                                                                                                             *
    8592*********************************************************************************************************************************/
    86 static RTONCE                       g_GetIoKitApisOnce = RTONCE_INITIALIZER;
    87 static PFNOSKEXTCOPYLOADEDKEXTINFO  g_pfnOSKextCopyLoadedKextInfo = NULL;
     93static RTONCE                                 g_GetIoKitApisOnce = RTONCE_INITIALIZER;
     94static PFNOSKEXTCOPYLOADEDKEXTINFO            g_pfnOSKextCopyLoadedKextInfo = NULL;
     95static PFNKEXTMANAGERLOADKEXTWITHURL          g_pfnKextManagerLoadKextWithUrl = NULL;
     96static PFNKEXTMANAGERLOADKEXTWITHIDENTIFIER   g_pfnKextManagerLoadKextWithIdentifier = NULL;
     97static PFNKEXTMANAGERUNLOADKEXTWITHIDENTIFIER g_pfnKextManagerUnloadKextWithIdentifier = NULL;
    8898
    8999/** Do-once callback for setting g_pfnOSKextCopyLoadedKextInfo.   */
     
    94104    int rc = RTLdrLoadEx("/System/Library/Frameworks/IOKit.framework/Versions/Current/IOKit", &hMod, RTLDRLOAD_FLAGS_NO_SUFFIX, NULL);
    95105    if (RT_SUCCESS(rc))
     106    {
    96107        RTLdrGetSymbol(hMod, "OSKextCopyLoadedKextInfo",  (void **)&g_pfnOSKextCopyLoadedKextInfo);
     108        RTLdrGetSymbol(hMod, "KextManagerLoadKextWithURL",  (void **)&g_pfnKextManagerLoadKextWithUrl);
     109        RTLdrGetSymbol(hMod, "KextManagerLoadKextWithIdentifier",  (void **)&g_pfnKextManagerLoadKextWithIdentifier);
     110        RTLdrGetSymbol(hMod, "KextManagerUnloadKextWithIdentifier",  (void **)&g_pfnKextManagerUnloadKextWithIdentifier);
     111    }
    97112
    98113    RT_NOREF(pvUser);
     
    390405    return VERR_NOT_IMPLEMENTED;
    391406}
     407
     408
     409RTDECL(int) RTKrnlModLoadByName(const char *pszName)
     410{
     411    AssertPtrReturn(pszName, VERR_INVALID_PARAMETER);
     412
     413    RTOnce(&g_GetIoKitApisOnce, rtKrnlModDarwinResolveIoKitApis, NULL);
     414    if (!g_pfnKextManagerLoadKextWithIdentifier) return VERR_NOT_SUPPORTED;
     415
     416    int rc = VINF_SUCCESS;
     417    CFStringRef hKextName = CFStringCreateWithCString(kCFAllocatorDefault, pszName, kCFStringEncodingUTF8);
     418    if (hKextName)
     419    {
     420        OSReturn rcOsx = g_pfnKextManagerLoadKextWithIdentifier(hKextName, NULL /*dependencyKextAndFolderURLs*/);
     421        if (rcOsx != kOSReturnSuccess)
     422            rc = VERR_NOT_SUPPORTED; /** @todo Convert OSReturn values. */
     423        CFRelease(hKextName);
     424    }
     425    else
     426        rc = VERR_NO_MEMORY;
     427
     428    return rc;
     429}
     430
     431
     432RTDECL(int) RTKrnlModLoadByPath(const char *pszPath)
     433{
     434    AssertPtrReturn(pszPath, VERR_INVALID_PARAMETER);
     435
     436    return VERR_NOT_SUPPORTED;
     437}
     438
     439
     440RTDECL(int) RTKrnlModUnloadByName(const char *pszName)
     441{
     442    AssertPtrReturn(pszName, VERR_INVALID_PARAMETER);
     443
     444    RTOnce(&g_GetIoKitApisOnce, rtKrnlModDarwinResolveIoKitApis, NULL);
     445    if (!g_pfnKextManagerUnloadKextWithIdentifier) return VERR_NOT_SUPPORTED;
     446
     447    int rc = VINF_SUCCESS;
     448    CFStringRef hKextName = CFStringCreateWithCString(kCFAllocatorDefault, pszName, kCFStringEncodingUTF8);
     449    if (hKextName)
     450    {
     451        OSReturn rcOsx = g_pfnKextManagerUnloadKextWithIdentifier(hKextName);
     452        if (rcOsx != kOSReturnSuccess)
     453            rc = VERR_NOT_SUPPORTED; /** @todo Convert OSReturn values. */
     454        CFRelease(hKextName);
     455    }
     456    else
     457        rc = VERR_NO_MEMORY;
     458
     459    return rc;
     460}
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