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: