diff --git a/HoRNDIS-Info.plist b/HoRNDIS-Info.plist index 54dc892..776a895 100644 --- a/HoRNDIS-Info.plist +++ b/HoRNDIS-Info.plist @@ -26,12 +26,12 @@ 1.0.0d1 IOKitPersonalities - HoRNDIS + HoRNDISDevice CFBundleIdentifier com.joshuawise.kexts.HoRNDIS IOClass - HoRNDIS + AppleUSBComposite IOProviderClass IOUSBDevice bDeviceClass @@ -41,6 +41,21 @@ bDeviceProtocol 0 + HoRNDISComposite + + CFBundleIdentifier + com.joshuawise.kexts.HoRNDIS + IOClass + HoRNDISUSBInterface + IOProviderClass + IOUSBInterface + bInterfaceClass + 224 + bInterfaceProtocol + 3 + bInterfaceSubClass + 1 + OSBundleLibraries diff --git a/HoRNDIS.cpp b/HoRNDIS.cpp index 37956be..9da3e18 100644 --- a/HoRNDIS.cpp +++ b/HoRNDIS.cpp @@ -39,6 +39,7 @@ #define super IOEthernetController OSDefineMetaClassAndStructors(HoRNDIS, IOEthernetController); +OSDefineMetaClassAndStructors(HoRNDISUSBInterface, HoRNDIS); OSDefineMetaClassAndStructors(HoRNDISInterface, IOEthernetInterface); bool HoRNDIS::init(OSDictionary *properties) { @@ -70,38 +71,30 @@ bool HoRNDIS::init(OSDictionary *properties) { /***** Driver setup and teardown language *****/ -bool HoRNDIS::start(IOService *provider) { - int cfg; - int rc; - - LOG(V_DEBUG, "starting up"); - if(!super::start(provider)) - return false; +bool HoRNDISUSBInterface::start(IOService *provider) { + IOUSBInterface *intf; - fpDevice = OSDynamicCast(IOUSBDevice, provider); - if(!fpDevice) { - stop(provider); + intf = OSDynamicCast(IOUSBInterface, provider); + if (!intf) { + LOG(V_ERROR, "cast to IOUSBInterface failed?"); return false; } + + fpDevice = intf->GetDevice(); + + return HoRNDIS::start(provider); +} + +bool HoRNDIS::start(IOService *provider) { + LOG(V_DEBUG, "starting up"); + if(!super::start(provider)) + return false; - /* Take control of the device before configuring. */ - if (!fpDevice->open(this)) { + if (!fpDevice) { stop(provider); return false; } - - /* Initialize and set the appropriate device configuration. */ - cfg = probeConfigurations(); - if (cfg < 0) - goto bailout; - - rc = fpDevice->SetConfiguration(this, cfg); - if (rc != kIOReturnSuccess) { - LOG(V_ERROR, "SetConfiguration on RNDIS config failed?"); - return false;; - } - /* Now do the rest of the work to actually bring it up... */ if (!openInterfaces()) goto bailout; if (!rndisInit()) @@ -142,11 +135,6 @@ void HoRNDIS::stop(IOService *provider) { fDataInterface = NULL; } - if (fpDevice) { - fpDevice->close(this); - fpDevice = NULL; - } - if (fMediumDict) { fMediumDict->release(); fMediumDict = NULL; @@ -155,59 +143,6 @@ void HoRNDIS::stop(IOService *provider) { super::stop(provider); } -/* Find and activate an RNDIS-looking interface. XXX: wish I could include that in configureDevice, below... */ -int HoRNDIS::probeConfigurations() { - int i; - int ncfgs = fpDevice->GetNumConfigurations(); - - /* XXX: Should probe the string descriptors to make sure that they match with Linux's RNDIS gadget strings; binding to arbitrary RNDIS devices probably won't work. */ - - LOG(V_DEBUG, "%d possible configs", ncfgs); - - for (i = 0; i < ncfgs; i++) { - IOUSBFindInterfaceRequest req; - const IOUSBConfigurationDescriptor *cd; - IOUSBInterfaceDescriptor *intf; - IOReturn ior; - - LOG(V_DEBUG, "checking configuration %d", i); - - cd = fpDevice->GetFullConfigurationDescriptor(i); - if (!cd) { - LOG(V_ERROR, "error retrieving configuration descriptor"); - continue; - } - - req.bInterfaceClass = 0xE0; - req.bInterfaceSubClass = 0x01; - req.bInterfaceProtocol = 0x03; - req.bAlternateSetting = kIOUSBFindInterfaceDontCare; - ior = fpDevice->FindNextInterfaceDescriptor(cd, NULL, &req, &intf); - if (ior != kIOReturnSuccess) { - LOG(V_DEBUG, "no control interface for configuration"); - continue; - } - - req.bInterfaceClass = 0x0A; - req.bInterfaceSubClass = 0x00; - req.bInterfaceProtocol = 0x00; - req.bAlternateSetting = kIOUSBFindInterfaceDontCare; - ior = fpDevice->FindNextInterfaceDescriptor(cd, intf, &req, &intf); - if (ior != kIOReturnSuccess) { - LOG(V_DEBUG, "no data interface for configuration"); - continue; - } - - LOG(V_DEBUG, "interface descriptor found"); - - /* Okay, we found it -- all set! */ - return cd->bConfigurationValue; - } - - LOG(V_ERROR, "no RNDIS configuration that I can drive"); - return -1; -} - bool HoRNDIS::openInterfaces() { IOUSBFindInterfaceRequest req; IOUSBFindEndpointRequest epReq; diff --git a/HoRNDIS.h b/HoRNDIS.h index e95dffd..6dcae91 100644 --- a/HoRNDIS.h +++ b/HoRNDIS.h @@ -271,7 +271,6 @@ class HoRNDIS : public IOEthernetController { bool allocateResources(void); void releaseResources(void); bool openInterfaces(); - int probeConfigurations(); bool createNetworkInterface(void); UInt32 outputPacket(mbuf_t pkt, void *param); IOReturn clearPipeStall(IOUSBPipe *thePipe); @@ -298,6 +297,13 @@ class HoRNDIS : public IOEthernetController { virtual IONetworkInterface *createInterface(); }; +/* If there are other ways to get access to a device, we probably want them here. */ +class HoRNDISUSBInterface : public HoRNDIS { + OSDeclareDefaultStructors(HoRNDISUSBInterface); +public: + virtual bool start(IOService *provider); +}; + class HoRNDISInterface : public IOEthernetInterface { OSDeclareDefaultStructors(HoRNDISInterface); public: