@@ -212,7 +212,73 @@ void USBToolBox::deleteProperty(IORegistryEntry* entry, const char* property) {
212212 }
213213}
214214
215+ OSObject* USBToolBox::fixMapForTahoe (OSObject* object) {
216+ OSDictionary* ports = OSDynamicCast (OSDictionary, object);
217+ if (!ports) {
218+ SYSTEMLOGPROV (" Ports is not a dictionary, skipping" );
219+ return object;
220+ }
221+
222+ OSDictionary* portsCopy = OSDynamicCast (OSDictionary, ports->copyCollection ());
223+ if (!portsCopy) {
224+ SYSTEMLOGPROV (" Failed to copy ports dictionary, skipping" );
225+ return object;
226+ }
227+ OSSafeReleaseNULL (ports);
228+
229+ const OSSymbol* portSymbol = OSSymbol::withCString (" port" );
230+ const OSSymbol* usbConnectorSymbol = OSSymbol::withCString (" UsbConnector" );
231+ const OSSymbol* portNumberSymbol = OSSymbol::withCString (" usb-port-number" );
232+ const OSSymbol* portTypeSymbol = OSSymbol::withCString (" usb-port-type" );
233+
234+ if (OSCollectionIterator* propertyIterator = OSCollectionIterator::withCollection (portsCopy)) {
235+ DEBUGLOGPROV (" Starting iteration over ports" );
236+ while (OSSymbol* key = OSDynamicCast (OSSymbol, propertyIterator->getNextObject ())) {
237+ OSObject* value = portsCopy->getObject (key);
238+ OSDictionary* portDict = OSDynamicCast (OSDictionary, value);
239+ if (!portDict) {
240+ DEBUGLOGPROV (" Port %s is not a dictionary, skipping" , key->getCStringNoCopy ());
241+ continue ;
242+ }
243+
244+ if (portDict->getObject (portNumberSymbol)) {
245+ DEBUGLOGPROV (" Port %s already has usb-port-number, skipping" , key->getCStringNoCopy ());
246+ } else if (!portDict->getObject (portSymbol)) {
247+ DEBUGLOGPROV (" Port %s does not have port, skipping" , key->getCStringNoCopy ());
248+ } else {
249+ DEBUGLOGPROV (" Port %s does not have usb-port-number, copying port to usb-port-number" , key->getCStringNoCopy ());
250+ portDict->setObject (portNumberSymbol, portDict->getObject (portSymbol));
251+ }
252+
253+ if (portDict->getObject (portTypeSymbol)) {
254+ DEBUGLOGPROV (" Port %s already has usb-port-type, skipping" , key->getCStringNoCopy ());
255+ } else if (!portDict->getObject (usbConnectorSymbol)) {
256+ DEBUGLOGPROV (" Port %s does not have UsbConnector, skipping" , key->getCStringNoCopy ());
257+ } else {
258+ DEBUGLOGPROV (" Port %s does not have usb-port-type, copying UsbConnector to usb-port-type" , key->getCStringNoCopy ());
259+ portDict->setObject (portTypeSymbol, portDict->getObject (usbConnectorSymbol));
260+ }
261+ }
262+ DEBUGLOGPROV (" Successfully fixed ports" );
263+ OSSafeReleaseNULL (propertyIterator);
264+ } else {
265+ SYSTEMLOGPROV (" Failed to create ports iterator!" );
266+ }
267+
268+ OSSafeReleaseNULL (portTypeSymbol);
269+ OSSafeReleaseNULL (usbConnectorSymbol);
270+ OSSafeReleaseNULL (portNumberSymbol);
271+ OSSafeReleaseNULL (portSymbol);
272+
273+ return portsCopy;
274+ }
275+
276+ extern const int version_major;
277+
278+
215279void USBToolBox::mergeProperties (IORegistryEntry* instance) {
280+ const OSSymbol* portsSymbol = OSSymbol::withCString (" ports" );
281+
216282 if (instance) {
217283 this ->controllerInstance = instance;
218284 }
@@ -238,8 +304,21 @@ void USBToolBox::mergeProperties(IORegistryEntry* instance) {
238304 if (OSCollectionIterator* propertyIterator = OSCollectionIterator::withCollection (properties)) {
239305 DEBUGLOGPROV (" Starting iteration over properties" );
240306 while (OSSymbol* key = OSDynamicCast (OSSymbol, propertyIterator->getNextObject ())) {
307+ OSObject* value = properties->getObject (key);
308+ if (!value) {
309+ DEBUGLOGPROV (" Property %s is null, skipping" , key->getCStringNoCopy ());
310+ continue ;
311+ }
312+ value->retain (); // Needed for proper handling in fixMapForTahoe
313+
314+ if (key == portsSymbol && version_major >= 25 ) {
315+ DEBUGLOGPROV (" Fixing map" );
316+ value = fixMapForTahoe (value);
317+ }
318+
241319 // DEBUGLOGPROV("Applied property %s", key->getCStringNoCopy());
242- this ->controllerInstance ->setProperty (key, properties->getObject (key));
320+ this ->controllerInstance ->setProperty (key, value);
321+ OSSafeReleaseNULL (value);
243322 }
244323 SYSTEMLOGPROV (" Successfully applied map" );
245324 OSSafeReleaseNULL (propertyIterator);
@@ -254,6 +333,7 @@ void USBToolBox::mergeProperties(IORegistryEntry* instance) {
254333 SYSTEMLOGPROV (" Map disabled, continuing" );
255334 }
256335 this ->controllerInstance ->release ();
336+ OSSafeReleaseNULL (portsSymbol);
257337}
258338
259339void USBToolBox::removeACPIPorts () {
0 commit comments