From f86ca426501a1648c76e0fc0be01ebd3030447d2 Mon Sep 17 00:00:00 2001 From: Dhinak G <17605561+dhinakg@users.noreply.github.com> Date: Tue, 10 Jun 2025 14:09:07 -0400 Subject: [PATCH 1/4] Bump to 1.2.0 --- USBToolBox.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/USBToolBox.xcodeproj/project.pbxproj b/USBToolBox.xcodeproj/project.pbxproj index 4941305..c24eb47 100644 --- a/USBToolBox.xcodeproj/project.pbxproj +++ b/USBToolBox.xcodeproj/project.pbxproj @@ -312,14 +312,14 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1.1.1; + CURRENT_PROJECT_VERSION = 1.2.0; INFOPLIST_FILE = USBToolBox/Info.plist; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/MacKernelSDK/Library/x86_64", ); MODULE_NAME = com.dhinakg.USBToolBox.kext; - MODULE_VERSION = 1.1.1; + MODULE_VERSION = 1.2.0; PRODUCT_BUNDLE_IDENTIFIER = com.dhinakg.USBToolBox.kext; PRODUCT_NAME = "$(TARGET_NAME)"; RUN_CLANG_STATIC_ANALYZER = YES; @@ -334,14 +334,14 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1.1.1; + CURRENT_PROJECT_VERSION = 1.2.0; INFOPLIST_FILE = USBToolBox/Info.plist; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/MacKernelSDK/Library/x86_64", ); MODULE_NAME = com.dhinakg.USBToolBox.kext; - MODULE_VERSION = 1.1.1; + MODULE_VERSION = 1.2.0; PRODUCT_BUNDLE_IDENTIFIER = com.dhinakg.USBToolBox.kext; PRODUCT_NAME = "$(TARGET_NAME)"; RUN_CLANG_STATIC_ANALYZER = YES; From f397910b813f4f58b069bdaa1c3605b4e6e517f1 Mon Sep 17 00:00:00 2001 From: Dhinak G <17605561+dhinakg@users.noreply.github.com> Date: Tue, 10 Jun 2025 14:11:22 -0400 Subject: [PATCH 2/4] Switch some logs to non-debug --- USBToolBox/USBToolBox.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/USBToolBox/USBToolBox.cpp b/USBToolBox/USBToolBox.cpp index 577129b..e922c79 100644 --- a/USBToolBox/USBToolBox.cpp +++ b/USBToolBox/USBToolBox.cpp @@ -150,7 +150,7 @@ IORegistryEntry* USBToolBox::getControllerViaMatching() { if (controller) { DEBUGLOGPROV("waitForMatchingService successful"); } else { - SYSTEMLOGPROV("waitForMatchingService failed or timed out"); + SYSTEMLOGPROV("waitForMatchingService failed or timed out, will try different method"); } return controller; } @@ -241,7 +241,7 @@ void USBToolBox::mergeProperties(IORegistryEntry* instance) { //DEBUGLOGPROV("Applied property %s", key->getCStringNoCopy()); this->controllerInstance->setProperty(key, properties->getObject(key)); } - DEBUGLOGPROV("Successfully applied map"); + SYSTEMLOGPROV("Successfully applied map"); OSSafeReleaseNULL(propertyIterator); } else { SYSTEMLOGPROV("Failed to create property iterator!"); @@ -321,7 +321,7 @@ IOService* USBToolBox::probe(IOService* provider, SInt32* score) { this->controllerInstance = getControllerViaMatching(); } if (!(this->controllerInstance)) { - DEBUGLOGPROV("Failed to obtain via matching in probe"); + SYSTEMLOGPROV("Failed to obtain via matching in probe, will try during start"); } else { mergeProperties(); DEBUGLOGPROV("Probe early finish"); @@ -341,7 +341,7 @@ bool USBToolBox::matchingCallback(OSDictionary* matchingDict, IOService* newServ // Should never be null, but better safe than sorry. OSSafeReleaseNULL(matchingDict); - DEBUGLOGPROV("controller callback end"); + SYSTEMLOGPROV("Controller notifier callback finished, goodbye!"); terminate(); return true; } @@ -357,12 +357,12 @@ bool USBToolBox::start(IOService *provider) { this->controllerInstance = getControllerViaMatching(); if (!(this->controllerInstance)) { - DEBUGLOGPROV("Failed to obtain via matching, falling back to iteration"); + SYSTEMLOGPROV("Failed to obtain via matching, falling back to iteration"); this->controllerInstance = getControllerViaIteration(); } if (!(this->controllerInstance)) { - DEBUGLOGPROV("Failed to obtain via iteration, falling back to notification"); + SYSTEMLOGPROV("Failed to obtain via iteration, falling back to notification"); OSDictionary* matchingDict = createMatchingDictionary(); if (!matchingDict) { @@ -376,10 +376,10 @@ bool USBToolBox::start(IOService *provider) { } // static IONotifier* addMatchingNotification(const OSSymbol* type, OSDictionary* matching, IOServiceMatchingNotificationHandler handler, void* target, void* ref = NULL, SInt32 priority = 0) IONotifier* notifierStatus = addMatchingNotification(gIOMatchedNotification, matchingDict, _matchingCallback, this, matchingDict); - DEBUGLOGPROV("Installed controller notifier status: %s", notifierStatus ? "successful" : "failed"); + SYSTEMLOGPROV("Installed controller notifier status: %s", notifierStatus ? "successful" : "failed"); } else { mergeProperties(); - DEBUGLOGPROV("Successfully applied properties, exiting"); + SYSTEMLOGPROV("Successfully applied properties, exiting"); return false; } DEBUGLOGPROV("start exit"); From 36466ecf53c27978d7a45245e93413ab37641396 Mon Sep 17 00:00:00 2001 From: Dhinak G <17605561+dhinakg@users.noreply.github.com> Date: Tue, 10 Jun 2025 14:11:33 -0400 Subject: [PATCH 3/4] First iteration of port fixing code --- USBToolBox/USBToolBox.cpp | 82 ++++++++++++++++++++++++++++++++++++++- USBToolBox/USBToolBox.hpp | 1 + 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/USBToolBox/USBToolBox.cpp b/USBToolBox/USBToolBox.cpp index e922c79..2f3affa 100644 --- a/USBToolBox/USBToolBox.cpp +++ b/USBToolBox/USBToolBox.cpp @@ -212,7 +212,73 @@ void USBToolBox::deleteProperty(IORegistryEntry* entry, const char* property) { } } +OSObject* USBToolBox::fixMapForTahoe(OSObject* object) { + OSDictionary* ports = OSDynamicCast(OSDictionary, object); + if (!ports) { + SYSTEMLOGPROV("Ports is not a dictionary, skipping"); + return object; + } + + OSDictionary* portsCopy = OSDynamicCast(OSDictionary, ports->copyCollection()); + if (!portsCopy) { + SYSTEMLOGPROV("Failed to copy ports dictionary, skipping"); + return object; + } + OSSafeReleaseNULL(ports); + + const OSSymbol* portSymbol = OSSymbol::withCString("port"); + const OSSymbol* usbConnectorSymbol = OSSymbol::withCString("UsbConnector"); + const OSSymbol* portNumberSymbol = OSSymbol::withCString("usb-port-number"); + const OSSymbol* portTypeSymbol = OSSymbol::withCString("usb-port-type"); + + if (OSCollectionIterator* propertyIterator = OSCollectionIterator::withCollection(portsCopy)) { + DEBUGLOGPROV("Starting iteration over ports"); + while (OSSymbol* key = OSDynamicCast(OSSymbol, propertyIterator->getNextObject())) { + OSObject* value = portsCopy->getObject(key); + OSDictionary* portDict = OSDynamicCast(OSDictionary, value); + if (!portDict) { + DEBUGLOGPROV("Port %s is not a dictionary, skipping", key->getCStringNoCopy()); + continue; + } + + if (portDict->getObject(portNumberSymbol)) { + DEBUGLOGPROV("Port %s already has usb-port-number, skipping", key->getCStringNoCopy()); + } else if (!portDict->getObject(portSymbol)) { + DEBUGLOGPROV("Port %s does not have port, skipping", key->getCStringNoCopy()); + } else { + DEBUGLOGPROV("Port %s does not have usb-port-number, copying port to usb-port-number", key->getCStringNoCopy()); + portDict->setObject(portNumberSymbol, portDict->getObject(portSymbol)); + } + + if (portDict->getObject(portTypeSymbol)) { + DEBUGLOGPROV("Port %s already has usb-port-type, skipping", key->getCStringNoCopy()); + } else if (!portDict->getObject(usbConnectorSymbol)) { + DEBUGLOGPROV("Port %s does not have UsbConnector, skipping", key->getCStringNoCopy()); + } else { + DEBUGLOGPROV("Port %s does not have usb-port-type, copying UsbConnector to usb-port-type", key->getCStringNoCopy()); + portDict->setObject(portTypeSymbol, portDict->getObject(usbConnectorSymbol)); + } + } + DEBUGLOGPROV("Successfully fixed ports"); + OSSafeReleaseNULL(propertyIterator); + } else { + SYSTEMLOGPROV("Failed to create ports iterator!"); + } + + OSSafeReleaseNULL(portTypeSymbol); + OSSafeReleaseNULL(usbConnectorSymbol); + OSSafeReleaseNULL(portNumberSymbol); + OSSafeReleaseNULL(portSymbol); + + return portsCopy; +} + +extern const int version_major; + + void USBToolBox::mergeProperties(IORegistryEntry* instance) { + const OSSymbol* portsSymbol = OSSymbol::withCString("ports"); + if (instance) { this->controllerInstance = instance; } @@ -238,8 +304,21 @@ void USBToolBox::mergeProperties(IORegistryEntry* instance) { if (OSCollectionIterator* propertyIterator = OSCollectionIterator::withCollection(properties)) { DEBUGLOGPROV("Starting iteration over properties"); while (OSSymbol* key = OSDynamicCast(OSSymbol, propertyIterator->getNextObject())) { + OSObject* value = properties->getObject(key); + if (!value) { + DEBUGLOGPROV("Property %s is null, skipping", key->getCStringNoCopy()); + continue; + } + value->retain(); // Needed for proper handling in fixMapForTahoe + + if (key == portsSymbol && version_major >= 25) { + DEBUGLOGPROV("Fixing map"); + value = fixMapForTahoe(value); + } + //DEBUGLOGPROV("Applied property %s", key->getCStringNoCopy()); - this->controllerInstance->setProperty(key, properties->getObject(key)); + this->controllerInstance->setProperty(key, value); + OSSafeReleaseNULL(value); } SYSTEMLOGPROV("Successfully applied map"); OSSafeReleaseNULL(propertyIterator); @@ -254,6 +333,7 @@ void USBToolBox::mergeProperties(IORegistryEntry* instance) { SYSTEMLOGPROV("Map disabled, continuing"); } this->controllerInstance->release(); + OSSafeReleaseNULL(portsSymbol); } void USBToolBox::removeACPIPorts() { diff --git a/USBToolBox/USBToolBox.hpp b/USBToolBox/USBToolBox.hpp index 1af5116..16ac32d 100644 --- a/USBToolBox/USBToolBox.hpp +++ b/USBToolBox/USBToolBox.hpp @@ -82,6 +82,7 @@ class USBToolBox : public IOService { static bool _matchingCallback(void* matchingDict, void* refCon, IOService* newService, IONotifier* notifier); IORegistryEntry* getControllerViaMatching(); IORegistryEntry* getControllerViaIteration(); + OSObject* fixMapForTahoe(OSObject* object); void mergeProperties(IORegistryEntry* instance = NULL); void removeACPIPorts(); From a22ea1ebbd7706da4eaf31b655796dad744c3ca8 Mon Sep 17 00:00:00 2001 From: Dhinak G <17605561+dhinakg@users.noreply.github.com> Date: Fri, 13 Jun 2025 10:59:17 -0400 Subject: [PATCH 4/4] Move kernel major declaration to headers --- USBToolBox/USBToolBox.cpp | 3 --- USBToolBox/USBToolBox.hpp | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/USBToolBox/USBToolBox.cpp b/USBToolBox/USBToolBox.cpp index 2f3affa..a85d6f1 100644 --- a/USBToolBox/USBToolBox.cpp +++ b/USBToolBox/USBToolBox.cpp @@ -273,9 +273,6 @@ OSObject* USBToolBox::fixMapForTahoe(OSObject* object) { return portsCopy; } -extern const int version_major; - - void USBToolBox::mergeProperties(IORegistryEntry* instance) { const OSSymbol* portsSymbol = OSSymbol::withCString("ports"); diff --git a/USBToolBox/USBToolBox.hpp b/USBToolBox/USBToolBox.hpp index 16ac32d..693b34b 100644 --- a/USBToolBox/USBToolBox.hpp +++ b/USBToolBox/USBToolBox.hpp @@ -34,6 +34,9 @@ #define DEBUGLOGPROV(format, args...) #endif +// Kernel major +extern const int version_major; + class USBToolBox : public IOService { OSDeclareDefaultStructors(USBToolBox)