diff --git a/AirportBrcmFixup/Info.plist b/AirportBrcmFixup/Info.plist
index e96d24f..7e44085 100644
--- a/AirportBrcmFixup/Info.plist
+++ b/AirportBrcmFixup/Info.plist
@@ -22,6 +22,19 @@
$(MODULE_VERSION)
IOKitPersonalities
+ as.lvs1974.AirportBrcmFixup
+
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ IOClass
+ $(PRODUCT_NAME:rfc1034identifier)
+ IOMatchCategory
+ $(PRODUCT_NAME:rfc1034identifier)
+ IOProviderClass
+ IOResources
+ IOResourceMatch
+ IOKit
+
as.lvs1974.FakeAirportBrcmFixup
CFBundleIdentifier
@@ -61,19 +74,6 @@
TruePowerOff
- as.lvs1974.AirportBrcmFixup
-
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- IOClass
- $(PRODUCT_NAME:rfc1034identifier)
- IOMatchCategory
- $(PRODUCT_NAME:rfc1034identifier)
- IOProviderClass
- IOResources
- IOResourceMatch
- IOKit
-
NSHumanReadableCopyright
Copyright © 2017 lvs1974. All rights reserved.
diff --git a/AirportBrcmFixup/kern_brcmfx.cpp b/AirportBrcmFixup/kern_brcmfx.cpp
index 6edecf9..a11a200 100644
--- a/AirportBrcmFixup/kern_brcmfx.cpp
+++ b/AirportBrcmFixup/kern_brcmfx.cpp
@@ -15,10 +15,6 @@
#include
#include
-#define kCFBundleIdentifierKey "CFBundleIdentifier"
-#define kCFBundleIdentifierKernelKey "CFBundleIdentifierKernel"
-#define KIOClass "IOClass"
-
// Only used in apple-driven callbacks
static BRCMFX *callbackBRCMFX {nullptr};
@@ -36,6 +32,7 @@ static bool kext_handled[kextListSize] {};
bool BRCMFX::init()
{
+ DBGLOG("BRCMFX", "init method is called");
callbackBRCMFX = this;
lilu.onPatcherLoadForce(
@@ -173,9 +170,9 @@ int32_t BRCMFX::siPmuFvcoPllreg(uint32_t *a1, int64_t a2, int64_t a3)
bool BRCMFX::start(IOService* service, IOService* provider)
{
- DBGLOG("BRCMFX", "start is called, service name is %s, provider name is %s", service->getName(), provider->getName());
+ DBGLOG("BRCMFX", "start is called, service name is %s, provider name is %s", safeString(service->getName()), safeString(provider->getName()));
- int index = find_service_index(service->getName());
+ int index = find_service_index(safeString(service->getName()));
int brcmfx_driver = ADDPR(brcmfx_config).brcmfx_driver;
if (brcmfx_driver == -1 && WIOKit::getOSDataValue(provider, Configuration::bootargBrcmDriver, brcmfx_driver)) {
DBGLOG("BRCMFX", "%s in ioreg is set to %d", Configuration::bootargBrcmDriver, brcmfx_driver);
@@ -187,7 +184,7 @@ bool BRCMFX::start(IOService* service, IOService* provider)
bool disable_driver = (brcmfx_driver == -1 && index == AirPort_BrcmNIC_MFG) || (brcmfx_driver != -1 && brcmfx_driver != index);
if (index < 0 || disable_driver)
{
- DBGLOG("BRCMFX", "start: disable service %s", service->getName());
+ DBGLOG("BRCMFX", "start: disable service %s", safeString(service->getName()));
return nullptr;
}
@@ -198,7 +195,7 @@ bool BRCMFX::start(IOService* service, IOService* provider)
DBGLOG("BRCMFX", "%s in ioreg is set to %s", Configuration::bootargBrcmCountry, callbackBRCMFX->provider_country_code);
}
- auto name = provider->getName();
+ auto name = safeString(provider->getName());
// There could be only one ARPT
if (!name || strcmp(name, "ARPT") != 0)
@@ -217,8 +214,8 @@ bool BRCMFX::start(IOService* service, IOService* provider)
IOService* BRCMFX::probe(IOService *service, IOService * provider, SInt32 *score)
{
- DBGLOG("BRCMFX", "probe is called, service name is %s, provider name is %s", service->getName(), provider->getName());
- int index = find_service_index(service->getName());
+ DBGLOG("BRCMFX", "probe is called, service name is %s, provider name is %s", safeString(service->getName()), safeString(provider->getName()));
+ int index = find_service_index(safeString(service->getName()));
int brcmfx_driver = ADDPR(brcmfx_config).brcmfx_driver;
if (brcmfx_driver == -1 && WIOKit::getOSDataValue(provider, Configuration::bootargBrcmDriver, brcmfx_driver)) {
DBGLOG("BRCMFX", "%s in ioreg is set to %d", Configuration::bootargBrcmDriver, brcmfx_driver);
@@ -230,7 +227,7 @@ IOService* BRCMFX::probe(IOService *service, IOService * provider, SInt32 *score
bool disable_driver = (brcmfx_driver == -1 && index == AirPort_BrcmNIC_MFG) || (brcmfx_driver != -1 && brcmfx_driver != index);
if (index < 0 || disable_driver)
{
- DBGLOG("BRCMFX", "probe: disable service %s", service->getName());
+ DBGLOG("BRCMFX", "probe: disable service %s", safeString(service->getName()));
return nullptr;
}
@@ -279,7 +276,7 @@ IOService* LIBKERN_RETURNS_NOT_RETAINED findService(const IORegistryPlane* plane
IORegistryEntry *res {nullptr};
while ((res = OSDynamicCast(IORegistryEntry, iterator->getNextObject())) != nullptr)
{
- const char *resname = res->getName();
+ auto resname = safeString(res->getName());
if (resname && !strncmp(service_name, resname, len))
{
service = OSDynamicCast(IOService, res);
@@ -298,6 +295,7 @@ IOService* LIBKERN_RETURNS_NOT_RETAINED findService(const IORegistryPlane* plane
void BRCMFX::processKernel(KernelPatcher &patcher)
{
+ DBGLOG("BRCMFX", "processKernel method is called");
if (!startMatching_symbol && !startMatching_dictionary)
{
startMatching_symbol = reinterpret_cast(patcher.solveSymbol(KernelPatcher::KernelID, "__ZN11IOCatalogue13startMatchingEPK8OSSymbol"));
@@ -306,13 +304,6 @@ void BRCMFX::processKernel(KernelPatcher &patcher)
SYSLOG("BRCMFX", "Fail to resolve IOCatalogue::startMatching method, error = %d", patcher.getError());
}
- if (!findDrivers)
- {
- findDrivers = reinterpret_cast(patcher.solveSymbol(KernelPatcher::KernelID, "__ZN11IOCatalogue11findDriversEP12OSDictionaryPi"));
- if (!findDrivers)
- SYSLOG("BRCMFX", "Fail to resolve IOCatalogue::findDrivers method, error = %d", patcher.getError());
- }
-
if (!removeDrivers)
{
removeDrivers = reinterpret_cast(patcher.solveSymbol(KernelPatcher::KernelID, "__ZN11IOCatalogue13removeDriversEP12OSDictionaryb"));
@@ -418,40 +409,6 @@ void BRCMFX::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
ADDPR(brcmfx_config).disabled = true;
- IOService *service = findService(gIOServicePlane, "FakeBrcm");
- if (service && service->getProvider())
- {
- auto bundle = OSDynamicCast(OSString, service->getProperty(kCFBundleIdentifierKey));
- auto ioclass = OSDynamicCast(OSString, service->getProperty(KIOClass));
- bool success = false;
-
- IOService *provider = service->getProvider();
- if (provider)
- {
- provider->retain();
- if (service->terminate())
- success = true;
- provider->release();
- DBGLOG("BRCMFX", "terminating FakeBrcm with status %d", success);
- }
- else
- success = true;
-
- if (success && bundle && ioclass && removeDrivers)
- {
- OSDictionary * dict = OSDictionary::withCapacity(2);
- if (dict) {
- dict->setObject(kCFBundleIdentifierKey, bundle);
- dict->setObject(KIOClass, ioclass);
- if (!removeDrivers(gIOCatalogue, dict, false))
- SYSLOG("BRCMFX", "gIOCatalogue->removeDrivers failed");
- else
- DBGLOG("BRCMFX", "gIOCatalogue->removeDrivers successful");
- OSSafeReleaseNULL(dict);
- }
- }
- }
-
if (!matchingTimer) {
if (!workLoop)
workLoop = IOWorkLoop::workLoop();
@@ -484,35 +441,67 @@ void BRCMFX::startMatching()
{
DBGLOG("BRCMFX", "startMatching is called");
-#ifdef DEBUG
- if (findDrivers) {
- for (int i=0; i < kextListSize; i++)
+ IOService *service = findService(gIOServicePlane, "FakeBrcm");
+ if (service && service->getProvider())
+ {
+ auto bundle = OSDynamicCast(OSString, service->getProperty(kCFBundleIdentifierKey));
+ auto ioclass = OSDynamicCast(OSString, service->getProperty(KIOClass));
+ bool success = false;
+
+ IOService *provider = service->getProvider();
+ if (provider)
{
- int brcmfx_driver = checkBrcmfxDriverValue(i, true);
- if (i != brcmfx_driver)
- continue;
- auto bundle = OSSymbol::withCStringNoCopy(idList[i]);
- if (!bundle)
- continue;
- OSDictionary * dict = OSDictionary::withCapacity(1);
+ provider->retain();
+ if (service->terminate())
+ success = true;
+ provider->release();
+ DBGLOG("BRCMFX", "terminating FakeBrcm with status %d", success);
+ }
+ else
+ success = true;
+
+ if (success && bundle && ioclass && removeDrivers)
+ {
+ OSDictionary * dict = OSDictionary::withCapacity(2);
if (dict) {
dict->setObject(kCFBundleIdentifierKey, bundle);
- SInt32 generation = 0;
- OSOrderedSet *set = findDrivers(gIOCatalogue, dict, &generation);
- if (set) {
- if (set->getCount() > 0)
- SYSLOG("BRCMFX", "gIOCatalogue->findDrivers() returned non-empty ordered set for bundle %s", idList[i]);
- else
- SYSLOG("BRCMFX", "gIOCatalogue->findDrivers() returned empty ordered set for bundle %s", idList[i]);
- }
- else {
- SYSLOG("BRCMFX", "gIOCatalogue->findDrivers() failed for bundle %s", idList[i]);
- }
+ dict->setObject(KIOClass, ioclass);
+ if (!removeDrivers(gIOCatalogue, dict, false))
+ SYSLOG("BRCMFX", "gIOCatalogue->removeDrivers failed");
+ else
+ DBGLOG("BRCMFX", "gIOCatalogue->removeDrivers successful");
OSSafeReleaseNULL(dict);
- OSSafeReleaseNULL(set);
}
}
}
+
+#ifdef DEBUG
+ for (int i=0; i < kextListSize; i++)
+ {
+ int brcmfx_driver = checkBrcmfxDriverValue(i, true);
+ if (i != brcmfx_driver)
+ continue;
+ auto bundle = OSSymbol::withCStringNoCopy(idList[i]);
+ if (!bundle)
+ continue;
+ OSDictionary * dict = OSDictionary::withCapacity(1);
+ if (dict) {
+ dict->setObject(kCFBundleIdentifierKey, bundle);
+ SInt32 generation = 0;
+ OSOrderedSet *set = gIOCatalogue->findDrivers(dict, &generation);
+ if (set) {
+ if (set->getCount() > 0)
+ DBGLOG("BRCMFX", "gIOCatalogue->findDrivers() returned non-empty ordered set for bundle %s", idList[i]);
+ else
+ DBGLOG("BRCMFX", "gIOCatalogue->findDrivers() returned empty ordered set for bundle %s", idList[i]);
+ }
+ else {
+ DBGLOG("BRCMFX", "gIOCatalogue->findDrivers() failed for bundle %s", idList[i]);
+ }
+ OSSafeReleaseNULL(dict);
+ OSSafeReleaseNULL(set);
+ }
+ }
#endif
if (startMatching_symbol)
diff --git a/AirportBrcmFixup/kern_brcmfx.hpp b/AirportBrcmFixup/kern_brcmfx.hpp
index 061a723..78ba397 100644
--- a/AirportBrcmFixup/kern_brcmfx.hpp
+++ b/AirportBrcmFixup/kern_brcmfx.hpp
@@ -51,7 +51,6 @@ class BRCMFX {
*/
using IOCatalogue_startMatching_symbol = bool (*)(void *that, OSSymbol const* bundle_identifier);
using IOCatalogue_startMatching_dictionary = bool (*)(void *that, OSDictionary *matching);
- using IOCatalogue_findDrivers = OSOrderedSet* (*)(void *that, OSDictionary *matching, SInt32 * generationCount);
using IOCatalogue_removeDrivers = bool (*)(void *that, OSDictionary *matching, bool doNubMatching);
/**
@@ -85,7 +84,6 @@ class BRCMFX {
// access to IOCatalogue methods
IOCatalogue_startMatching_symbol startMatching_symbol {};
IOCatalogue_startMatching_dictionary startMatching_dictionary {};
- IOCatalogue_findDrivers findDrivers {};
IOCatalogue_removeDrivers removeDrivers {};
char provider_country_code[5] {""};
diff --git a/AirportBrcmFixup/kern_fakebrcm.cpp b/AirportBrcmFixup/kern_fakebrcm.cpp
index 21458e0..5dba41e 100644
--- a/AirportBrcmFixup/kern_fakebrcm.cpp
+++ b/AirportBrcmFixup/kern_fakebrcm.cpp
@@ -11,7 +11,7 @@
#include "kern_fakebrcm.hpp"
#include "kern_misc.hpp"
#include
-
+#include
OSDefineMetaClassAndStructors(FakeBrcm, IOService);
@@ -31,7 +31,7 @@ bool PCIHookManager::isServiceSupported(IORegistryEntry* service)
for (int i=0; igetName()) == 0)
+ if (strcmp(serviceNameList[i], safeString(service->getName())) == 0)
return true;
}
return false;
@@ -64,7 +64,7 @@ UInt16 PCIHookManager::configRead16(IORegistryEntry *service, UInt32 space, UInt
}
if (newResult != result)
- DBGLOG("BRCMFX", "PCIHookManager::configRead16: name = %s, source value = 0x%04x replaced with value = 0x%04x", service->getName(), result, newResult);
+ DBGLOG("BRCMFX", "PCIHookManager::configRead16: name = %s, source value = 0x%04x replaced with value = 0x%04x", safeString(service->getName()), result, newResult);
return newResult;
}
@@ -87,7 +87,7 @@ UInt32 PCIHookManager::configRead32(IORegistryEntry *service, UInt32 space, UInt
}
if (newResult != result)
- DBGLOG("BRCMFX", "PCIHookManager::configRead32: name = %s, source value = 0x%08x replaced with value = 0x%08x", service->getName(), result, newResult);
+ DBGLOG("BRCMFX", "PCIHookManager::configRead32: name = %s, source value = 0x%08x replaced with value = 0x%08x", safeString(service->getName()), result, newResult);
return newResult;
}
@@ -96,6 +96,8 @@ UInt32 PCIHookManager::configRead32(IORegistryEntry *service, UInt32 space, UInt
void PCIHookManager::hookProvider(IOService *provider)
{
+ awaitPublishing(provider);
+
auto pciDevice = OSDynamicCast(IOPCIDevice, provider);
if (!pciDevice) {
DBGLOG("BRCMFX", "Provider is not IOPCIDevice");
@@ -168,6 +170,32 @@ void PCIHookManager::hookProvider(IOService *provider)
DBGLOG("BRCMFX", "PCIHookManager::hookProvider for configRead32 was successful");
}
+//==============================================================================
+
+bool PCIHookManager::awaitPublishing(IORegistryEntry *obj)
+{
+ size_t counter = 0;
+ while (counter < 256) {
+ if (obj->inPlane(gIOServicePlane)) {
+ DBGLOG("BRCMFX", "pci device %s is in service plane %lu", safeString(obj->getName()), counter);
+ return true;
+ }
+ DBGLOG("BRCMFX", "pci device %s is not in service plane %lu, polling", safeString(obj->getName()), counter);
+
+ if (obj->getProperty("IOPCIConfigured")) {
+ DBGLOG("dev", "pci bridge %s is configured %lu", safeString(obj->getName()), counter);
+ break;
+ }
+ DBGLOG("BRCMFX", "pci bridge %s is not configured %lu, polling", safeString(obj->getName()), counter);
+ ++counter;
+ IOSleep(20);
+ }
+
+ SYSLOG("BRCMFX", "found dead pci device %s", safeString(obj->getName()));
+ return false;
+}
+
+
//==============================================================================
bool FakeBrcm::init(OSDictionary *propTable)
@@ -223,7 +251,7 @@ IOService* FakeBrcm::probe(IOService * provider, SInt32 *score)
return ret;
}
- DBGLOG("BRCMFX", "FakeBrcm::probe(): service provider is %s", provider->getName());
+ DBGLOG("BRCMFX", "FakeBrcm::probe(): service provider is %s", safeString(provider->getName()));
for (int i = 0; i < kextListSize; i++)
{
@@ -231,20 +259,29 @@ IOService* FakeBrcm::probe(IOService * provider, SInt32 *score)
if (i != brcmfx_driver)
continue;
- const OSMetaClass * meta_class = OSMetaClass::getMetaClassWithName(OSSymbol::withCStringNoCopy(serviceNameList[i]));
- if (meta_class != nullptr)
- {
- DBGLOG("BRCMFX", "FakeBrcm::probe(): meta class for %s exists!", serviceNameList[i]);
-
- IOService *service = OSDynamicCast(IOService, meta_class->alloc());
- if (service != nullptr)
- {
- service->retain();
- DBGLOG("BRCMFX", "FakeBrcm: retain counter for driver %s is %d", serviceNameList[i], service->getRetainCount());
- service_found = true;
+ auto bundle = OSSymbol::withCStringNoCopy(idList[i]);
+ if (bundle) {
+ OSDictionary * dict = OSDictionary::withCapacity(1);
+ if (dict) {
+ dict->setObject(kCFBundleIdentifierKey, bundle);
+ SInt32 generation = 0;
+ OSOrderedSet *set = gIOCatalogue->findDrivers(dict, &generation);
+ if (set) {
+ if (set->getCount() > 0)
+ {
+ DBGLOG("BRCMFX", "FakeBrcm::probe(): gIOCatalogue->findDrivers() returned non-empty ordered set for bundle %s", idList[i]);
+ service_found = true;
+
+ }
+ else
+ DBGLOG("BRCMFX", "FakeBrcm::probe(): gIOCatalogue->findDrivers() returned empty ordered set for bundle %s", idList[i]);
+ }
+ else {
+ SYSLOG("BRCMFX", "FakeBrcm::probe(): gIOCatalogue->findDrivers() failed for bundle %s", idList[i]);
+ }
+ OSSafeReleaseNULL(dict);
+ OSSafeReleaseNULL(set);
}
- else
- SYSLOG("BRCMFX", "FakeBrcm: instance of driver %s couldn't be created", serviceNameList[i]);
}
}
diff --git a/AirportBrcmFixup/kern_fakebrcm.hpp b/AirportBrcmFixup/kern_fakebrcm.hpp
index a713fe0..44d0bb3 100644
--- a/AirportBrcmFixup/kern_fakebrcm.hpp
+++ b/AirportBrcmFixup/kern_fakebrcm.hpp
@@ -25,6 +25,7 @@ class EXPORT PCIHookManager
public:
static void hookProvider(IOService* provider);
+ static bool awaitPublishing(IORegistryEntry *obj);
};
class EXPORT FakeBrcm : public IOService
diff --git a/AirportBrcmFixup/kern_misc.hpp b/AirportBrcmFixup/kern_misc.hpp
index 4b864cc..7d00bdc 100644
--- a/AirportBrcmFixup/kern_misc.hpp
+++ b/AirportBrcmFixup/kern_misc.hpp
@@ -10,6 +10,10 @@
#include
+#define kCFBundleIdentifierKey "CFBundleIdentifier"
+#define kCFBundleIdentifierKernelKey "CFBundleIdentifierKernel"
+#define KIOClass "IOClass"
+
static const size_t kextListSize {4};
enum AirportServices {