コード例 #1
0
ファイル: usbnet.c プロジェクト: pettair/libusbnet
int usb_get_driver_np(usb_dev_handle *dev, int interface, char *name, unsigned int namelen)
{
   // Get remote fd
   Packet* pkt = pkt_claim();
   int fd = session_get();

   // Send packet
   pkt_init(pkt, UsbGetKernelDriver);
   pkt_addint(pkt,  dev->fd);
   pkt_addint(pkt,  interface);
   pkt_adduint(pkt, namelen);
   pkt_send(pkt, fd);

   // Get response
   int res = -1;
   if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbGetKernelDriver) {
      Iterator it;
      pkt_begin(pkt, &it);
      res = iter_getint(&it);

      // Error
      if(res) {
         error_msg("%s: could not get bound driver", __func__);
      }

      // Save string
      strncpy(name, iter_getstr(&it), namelen - 1);
      name[namelen - 1] = '\0';
   }

   pkt_release();
   debug_msg("returned %d (%s)", res, name);
   return res;
}
コード例 #2
0
ファイル: usbnet.c プロジェクト: pettair/libusbnet
/* libusb(5):
 * Interrupt transfers.
 */
int usb_interrupt_write(usb_dev_handle *dev, int ep, usb_buf_t bytes, int size, int timeout)
{
   // Get remote fd
   Packet* pkt = pkt_claim();
   int fd = session_get();

   // Prepare packet
   pkt_init(pkt, UsbInterruptWrite);
   pkt_addint(pkt, dev->fd);
   pkt_addint(pkt, ep);
   pkt_addstr(pkt, size, bytes);
   pkt_addint(pkt, timeout);
   pkt_send(pkt, fd);

   // Get response
   int res = -1;
   if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbInterruptWrite) {
      Iterator it;
      pkt_begin(pkt, &it);
      res = iter_getint(&it);
   }

   // Return response
   pkt_release();
   debug_msg("returned %d", res);
   return res;
}
コード例 #3
0
ファイル: usbnet.c プロジェクト: pettair/libusbnet
int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout)
{
   // Get remote fd
   Packet* pkt = pkt_claim();
   int fd = session_get();

   // Prepare packet
   pkt_init(pkt, UsbInterruptRead);
   pkt_addint(pkt, dev->fd);
   pkt_addint(pkt, ep);
   pkt_addint(pkt, size);
   pkt_addint(pkt, timeout);
   pkt_send(pkt, fd);

   // Get response
   int res = -1;
   if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbInterruptRead) {
      Iterator it;
      pkt_begin(pkt, &it);
      res = iter_getint(&it);

      if(res > 0) {
         int minlen = (res > size) ? size : res;
         memcpy(bytes, it.val, minlen);
      }

   }

   // Return response
   pkt_release();
   debug_msg("returned %d", res);
   return res;
}
コード例 #4
0
ファイル: usbnet.c プロジェクト: pettair/libusbnet
int usb_reset(usb_dev_handle *dev)
{
   // Get remote fd
   Packet* pkt = pkt_claim();
   int fd = session_get();

   // Prepare packet
   pkt_init(pkt, UsbReset);
   pkt_addint(pkt, dev->fd);
   pkt_send(pkt, fd);

   // Get response
   int res = -1;
   if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbReset) {
      Iterator it;
      pkt_begin(pkt, &it);

      // Read result
      res = iter_getint(&it);
   }

   // Return response
   pkt_release();
   debug_msg("returned %d", res);
   return res;
}
コード例 #5
0
ファイル: usbnet.c プロジェクト: pettair/libusbnet
int usb_close(usb_dev_handle *dev)
{
   // Get remote fd
   Packet* pkt = pkt_claim();
   int fd = session_get();

   // Send packet
   pkt_init(pkt, UsbClose);
   pkt_addint(pkt, dev->fd);
   pkt_send(pkt, fd);

   // Free device
   free(dev);

   // Get response
   int res = -1;
   if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbClose) {
      Iterator it;
      pkt_begin(pkt, &it);
      res = iter_getint(&it);
   }

   pkt_release();
   debug_msg("returned %d", res);
   return res;
}
コード例 #6
0
ファイル: usbnet.c プロジェクト: pettair/libusbnet
int usb_set_altinterface(usb_dev_handle *dev, int alternate)
{
   // Get remote fd
   Packet* pkt = pkt_claim();
   int fd = session_get();

   // Prepare packet
   pkt_init(pkt, UsbSetAltInterface);
   pkt_addint(pkt, dev->fd);
   pkt_addint(pkt, alternate);
   pkt_send(pkt, fd);

   // Get response
   int res = -1;
   if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbSetAltInterface) {
      Iterator it;
      pkt_begin(pkt, &it);

      // Read result
      res = iter_getint(&it);

      // Read callback configuration
      alternate = iter_getint(&it);
   }

   // Save configuration
   dev->altsetting = alternate;

   // Return response
   pkt_release();
   debug_msg("returned %d", res);
   return res;
}
コード例 #7
0
ファイル: usbnet.c プロジェクト: pettair/libusbnet
usb_dev_handle *usb_open(struct usb_device *dev)
{
   // Get remote fd
   Packet* pkt = pkt_claim();
   int fd = session_get();

   // Send packet
   pkt_init(pkt, UsbOpen);
   pkt_adduint(pkt, dev->bus->location);
   pkt_adduint(pkt, dev->devnum);
   pkt_send(pkt, fd);

   // Get response
   int res = -1, devfd = -1;
   if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbOpen) {
      Iterator it;
      pkt_begin(pkt, &it);
      res = iter_getint(&it);
      devfd = iter_getint(&it);
   }

   // Evaluate
   usb_dev_handle* udev = NULL;
   if(res >= 0) {
      udev = malloc(sizeof(usb_dev_handle));
      udev->fd = devfd;
      udev->device = dev;
      udev->bus = dev->bus;
      udev->config = udev->interface = udev->altsetting = -1;
   }

   pkt_release();
   debug_msg("returned %d (fd %d)", res, devfd);
   return udev;
}
コード例 #8
0
ファイル: pcsed.c プロジェクト: ya-mouse/dos-utils
/**
 * Release the hardware driver.
 */
void _eth_release (void)
{
  if (!_eth_is_init)
     return;

  /* Set original MAC address (if not fatal-error or serial-driver)
   */
  if (!_watt_fatal_error)
  {
    if (!_pktserial)
    {
      if (memcmp(&_eth_addr, &_eth_real_addr, sizeof(_eth_addr)))
         pkt_set_addr (&_eth_real_addr);

#if defined(USE_MULTICAST) || defined(USE_IPV6) /* restore startup Rx mode */
      if (_pkt_rxmode0 > -1 && _pkt_rxmode0 != _pkt_rxmode)
         pkt_set_rcv_mode (_pkt_rxmode0);
#endif
    }

#if defined(USE_DEBUG)
    if (debug_on > 0)
    {
      DWORD drops = pkt_dropped();
      if (drops)
        (*_printf) ("%lu packets dropped\n", drops);
    }
#endif
  }
  _eth_is_init = FALSE;  /* in case we crash in pkt_release() */
  pkt_release();
}
コード例 #9
0
ファイル: usbnet.c プロジェクト: pettair/libusbnet
/** Initialize USB subsystem. */
void usb_init(void)
{
   // Initialize packet & remote fd
   Packet* pkt = pkt_claim();
   int fd = session_get();

   // Create buffer
   pkt_init(pkt, UsbInit);
   pkt_send(pkt, fd);
   pkt_release();

   // Initialize locally
   debug_msg("called");
}
コード例 #10
0
ファイル: usbnet.c プロジェクト: pettair/libusbnet
int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
        int value, int index, char *bytes, int size, int timeout)
{
   // Get remote fd
   Packet* pkt = pkt_claim();
   int fd = session_get();

   // Prepare packet
   pkt_init(pkt, UsbControlMsg);
   pkt_addint(pkt, dev->fd);
   pkt_addint(pkt, requesttype);
   pkt_addint(pkt, request);
   pkt_addint(pkt, value);
   pkt_addint(pkt, index);
   pkt_addstr(pkt, size, bytes);
   pkt_addint(pkt, timeout);
   pkt_send(pkt, fd);

   // Get response
   int res = -1;
   if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbControlMsg) {
      Iterator it;
      pkt_begin(pkt, &it);
      res = iter_getint(&it);

      if(res > 0) {
         int minlen = (res > size) ? size : res;
         memcpy(bytes, it.val, minlen);
      }

   }

   // Return response
   pkt_release();
   debug_msg("returned %d", res);
   return res;
}
コード例 #11
0
ファイル: usbnet.c プロジェクト: pettair/libusbnet
int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface)
{
   // Get remote fd
   Packet* pkt = pkt_claim();
   int fd = session_get();

   // Send packet
   pkt_init(pkt, UsbDetachKernelDriver);
   pkt_addint(pkt, dev->fd);
   pkt_addint(pkt, interface);
   pkt_send(pkt, fd);

   // Get response
   int res = -1;
   if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbDetachKernelDriver) {
      Iterator it;
      pkt_begin(pkt, &it);
      res = iter_getint(&it);
   }

   pkt_release();
   debug_msg("returned %d", res);
   return res;
}
コード例 #12
0
ファイル: usbnet.c プロジェクト: pettair/libusbnet
/** Find busses on remote host.
    \warning Does not transfer busses to local virtual bus list.
  */
int usb_find_busses(void)
{
  // Get remote fd
   Packet* pkt = pkt_claim();
   int fd = session_get();

   // Initialize pkt
   pkt_init(pkt, UsbFindBusses);
   pkt_send(pkt, fd);

   // Get number of changes
   int res = 0;
   Iterator it;
   if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbFindBusses) {
      if(pkt_begin(pkt, &it) != NULL) {
         res = iter_getint(&it);
      }
   }

   // Return remote result
   pkt_release();
   debug_msg("returned %d", res);
   return res;
}
コード例 #13
0
ファイル: winpcap.c プロジェクト: ya-mouse/dos-utils
/**
 * Initialise WinPcap and return our MAC address.
 */
int pkt_eth_init (mac_address *mac_addr)
{
  struct {
    PACKET_OID_DATA oidData;
    char            descr[512];
  } oid;
  const ADAPTER *adapter = NULL;
  DWORD thread_id;
  BOOL  is_up;

  if (_watt_is_win9x)  /**< \todo Support Win-9x too */
  {
    (*_printf) (_LANG("Win-NT or later reqired.\n"));
    _pkt_errno = PDERR_GEN_FAIL;
    return (WERR_ILL_DOSX);
  }

  if (!_watt_no_config || _watt_user_config_fn)
     parse_config_pass_1();

  _pkt_inf = calloc (sizeof(*_pkt_inf), 1);
  if (!_pkt_inf)
  {
    (*_printf) (_LANG("Failed to allocate WinPcap DRIVER data.\n"));
    _pkt_errno = PDERR_GEN_FAIL;
    return (WERR_NO_MEM);
  }

  if (debug_on >= 2 && dump_fname[0])
     dump_file = fopen_excl (ExpandVarStr(dump_fname), "w+t");

  if (!PacketInitModule(TRUE, dump_file))
  {
    (*_printf) (_LANG("Failed to initialise WinPcap.\n"));
    pkt_release();
    _pkt_errno = PDERR_NO_DRIVER;
    return (WERR_PKT_ERROR);
  }

  if (!_pktdrvrname[0] &&
      !find_adapter(_pktdrvrname,sizeof(_pktdrvrname)))
  {
    (*_printf) (_LANG("No WinPcap driver found.\n"));
    _pkt_errno = PDERR_NO_DRIVER;
    return (WERR_NO_DRIVER);
  }

  TCP_CONSOLE_MSG (2, ("device %s\n", _pktdrvrname));

  adapter = PacketOpenAdapter (_pktdrvrname);
  if (!adapter)
  {
    if (debug_on > 0)
       (*_printf) (_LANG("PacketOpenAdapter (\"%s\") failed; %s\n"),
                   _pktdrvrname, win_strerror(GetLastError()));
    pkt_release();
    return (WERR_NO_DRIVER);
  }

  _pkt_inf->adapter = adapter;
#if defined(USE_DYN_PACKET)
  _pkt_inf->adapter_info = NULL;
#else
  _pkt_inf->adapter_info = PacketFindAdInfo (_pktdrvrname);
#endif

  /* Query the NIC driver for the adapter description
   */
  memset (&oid, 0, sizeof(oid));
  oid.oidData.Oid    = OID_GEN_VENDOR_DESCRIPTION;
  oid.oidData.Length = sizeof(oid.descr);

  if (PacketRequest (adapter, FALSE, &oid.oidData))
     StrLcpy (_pktdrvr_descr, (char*)oid.oidData.Data, sizeof(_pktdrvr_descr));
  else
  {
    (*_printf) (_LANG("PacketRequest() failed; %s\n"),
                win_strerror(GetLastError()));
    pkt_release();
    return (WERR_PKT_ERROR);
  }

  if (!get_interface_type(&_pktdevclass))
  {
    pkt_release();
    return (WERR_PKT_ERROR);
  }

  if (get_connected_status(&is_up) && !is_up)
     (*_printf) (_LANG("Warning: the adapter %s is down\n"), _pktdrvrname);

  switch (_pktdevclass)
  {
    case PDCLASS_TOKEN:
         _pkt_ip_ofs = sizeof(tok_Header);
         break;
    case PDCLASS_ETHER:
         _pkt_ip_ofs = sizeof(eth_Header);
         break;
    case PDCLASS_FDDI:
         _pkt_ip_ofs = sizeof(fddi_Header);
         break;
    case PDCLASS_ARCNET:
         _pkt_ip_ofs = ARC_HDRLEN;
         break;
    default:
         pkt_release();
         (*_printf) (_LANG("WinPcap-ERROR: Unsupported driver class %dh\n"),
                     _pktdevclass);
         _pkt_errno = PDERR_NO_CLASS;
         return (WERR_PKT_ERROR);
  }

  if (!pkt_get_addr(mac_addr))  /* get our MAC address */
  {
    pkt_release();
    return (WERR_PKT_ERROR);
  }

  pktq_init (&_pkt_inf->pkt_queue,
             sizeof(_pkt_inf->rx_buf[0]),   /* RX_SIZE */
             DIM(_pkt_inf->rx_buf),         /* RX_BUFS */
             (char*)&_pkt_inf->rx_buf);

  _pkt_inf->npf_buf_size = RX_SIZE * pkt_num_rx_bufs;
  _pkt_inf->npf_buf = malloc (_pkt_inf->npf_buf_size);
  if (!_pkt_inf->npf_buf)
  {
    (*_printf) (_LANG("Failed to allocate %d byte Rx buffer.\n"),
                _pkt_inf->npf_buf_size);
    pkt_release();
    _pkt_errno = PDERR_GEN_FAIL;
    return (WERR_NO_MEM);
  }

  PacketSetMode (adapter, PACKET_MODE_CAPT);
  PacketSetBuff (adapter, _pkt_inf->npf_buf_size);
  PacketSetMinToCopy (adapter, ETH_MIN);

  /* PacketReceivePacket() blocks until something is received
   */
  PacketSetReadTimeout ((ADAPTER*)adapter, 0);

  /* Set Rx-mode forced via config.
   */
  if (_pkt_forced_rxmode != -1)
  {
    _pkt_forced_rxmode &= 0xFFFF;     /* clear bits not set via ARG_ATOX_W */
    if (_pkt_forced_rxmode == 0 ||    /* check illegal bit-values */
        (_pkt_forced_rxmode & 0x10) ||
        (_pkt_forced_rxmode & 0x40) ||
        (_pkt_forced_rxmode > 0x80))
     {
       TCP_CONSOLE_MSG (0, ("Illegal Rx-mode (0x%02X) specified\n",
                        _pkt_forced_rxmode));
       _pkt_forced_rxmode = -1;
     }
  }

  if (pkt_get_rcv_mode())
     _pkt_rxmode0 = _pkt_rxmode;

  if (_pkt_forced_rxmode != -1)
       pkt_set_rcv_mode (_pkt_forced_rxmode);
  else pkt_set_rcv_mode (RXMODE_DEFAULT);

#if 1
  _pkt_inf->recv_thread = CreateThread (NULL, 2048, pkt_recv_thread,
                                        NULL, 0, &thread_id);
#else
  _pkt_inf->recv_thread = _beginthreadex (NULL, 2048, pkt_recv_thread,
                                          NULL, 0, &thread_id);
#endif

  if (!_pkt_inf->recv_thread)
  {
    (*_printf) (_LANG("Failed to create receiver thread; %s\n"),
                win_strerror(GetLastError()));
    pkt_release();
    _pkt_errno = PDERR_GEN_FAIL;
    return (WERR_PKT_ERROR);
  }

  if (thr_realtime)
     SetThreadPriority (_pkt_inf->recv_thread,
                        THREAD_PRIORITY_TIME_CRITICAL);

  TCP_CONSOLE_MSG (2, ("capture thread-id %lu\n", thread_id));

#if defined(USE_DEBUG)
  if (debug_on >= 2)
  {
    (*_printf) ("link-details:\n");
    show_link_details();
  }
#endif
  return (0);
}
コード例 #14
0
ファイル: usbnet.c プロジェクト: pettair/libusbnet
/** Find devices on remote host.
  * Create new devices on local virtual bus.
  * \warning Function replaces global usb_busses variable from libusb.
  */
int usb_find_devices(void)
{
   // Get remote fd
   Packet* pkt = pkt_claim();
   int fd = session_get();

   // Create buffer
   pkt_init(pkt, UsbFindDevices);
   pkt_send(pkt, fd);

   // Get number of changes
   int res = 0;
   Iterator it;
   if(pkt_recv(fd, pkt) > 0) {
      pkt_begin(pkt, &it);

      // Get return value
      res = iter_getint(&it);

      // Allocate virtualbus
      struct usb_bus vbus;
      vbus.next = __remote_bus;
      struct usb_bus* rbus = &vbus;

      // Get busses
      while(!iter_end(&it)) {

         // Evaluate
         if(it.type == StructureType) {
            iter_enter(&it);

            // Allocate bus
            if(rbus->next == NULL) {

               // Allocate next item
               struct usb_bus* nbus = malloc(sizeof(struct usb_bus));
               memset(nbus, 0, sizeof(struct usb_bus));
               rbus->next = nbus;
               nbus->prev = rbus;
               rbus = nbus;
            }
            else
               rbus = rbus->next;

            // Read dirname
            strcpy(rbus->dirname, iter_getstr(&it));

            // Read location
            rbus->location = iter_getuint(&it);

            // Read devices
            struct usb_device vdev;
            vdev.next = rbus->devices;
            struct usb_device* dev = &vdev;
            while(it.type == SequenceType) {
               iter_enter(&it);

               // Initialize
               if(dev->next == NULL) {
                  dev->next = malloc(sizeof(struct usb_device));
                  memset(dev->next, 0, sizeof(struct usb_device));
                  dev->next->bus = rbus;
                  if(dev != &vdev)
                     dev->next->prev = dev;
                  if(rbus->devices == NULL)
                     rbus->devices = dev->next;
               }

               dev = dev->next;

               // Read filename
               strcpy(dev->filename, iter_getstr(&it));

               // Read devnum
               dev->devnum = iter_getuint(&it);

               // Read descriptor
               // Apply byte-order conversion for 16/32bit integers
               memcpy(&dev->descriptor, it.val, it.len);
               dev->descriptor.bcdUSB = ntohs(dev->descriptor.bcdUSB);
               dev->descriptor.idVendor = ntohs(dev->descriptor.idVendor);
               dev->descriptor.idProduct = ntohs(dev->descriptor.idProduct);
               dev->descriptor.bcdDevice = ntohs(dev->descriptor.bcdDevice);
               iter_next(&it);

               // Alloc configurations
               unsigned cfgid = 0, cfgnum = dev->descriptor.bNumConfigurations;
               dev->config = NULL;
               if(cfgnum > 0) {
                  dev->config = malloc(cfgnum * sizeof(struct usb_config_descriptor));
                  memset(dev->config, 0, cfgnum * sizeof(struct usb_config_descriptor));
               }

               // Read config
               while(it.type == RawType && cfgid < cfgnum) {
                  struct usb_config_descriptor* cfg = &dev->config[cfgid];
                  ++cfgid;

                  // Ensure struct under/overlap
                  int szlen = sizeof(struct usb_config_descriptor);
                  if(szlen > it.len)
                     szlen = it.len;

                  // Read config and apply byte-order conversion
                  memcpy(cfg, it.val, szlen);
                  cfg->wTotalLength = ntohs(cfg->wTotalLength);

                  // Allocate interfaces
                  cfg->interface = NULL;
                  if(cfg->bNumInterfaces > 0) {
                     cfg->interface = malloc(cfg->bNumInterfaces * sizeof(struct usb_interface));
                  }

                  //! \test Implement usb_device extra interfaces - are they needed?
                  cfg->extralen = 0;
                  cfg->extra = NULL;
                  iter_next(&it);

                  // Load interfaces
                  unsigned i, j, k;
                  for(i = 0; i < cfg->bNumInterfaces; ++i) {
                     struct usb_interface* iface = &cfg->interface[i];

                     // Read altsettings count
                     iface->num_altsetting = iter_getint(&it);

                     // Allocate altsettings
                     if(iface->num_altsetting > 0) {
                        iface->altsetting = malloc(iface->num_altsetting * sizeof(struct usb_interface_descriptor));
                     }

                     // Load altsettings
                     for(j = 0; j < iface->num_altsetting; ++j) {

                        // Ensure struct under/overlap
                        struct usb_interface_descriptor* as = &iface->altsetting[j];
                        int szlen = sizeof(struct usb_interface_descriptor);
                        if(szlen > it.len)
                           szlen = it.len;

                        // Read altsettings - no conversions apply
                        memcpy(as, it.val, szlen);
                        iter_next(&it);

                        // Allocate endpoints
                        as->endpoint = NULL;
                        if(as->bNumEndpoints > 0) {
                           size_t epsize = as->bNumEndpoints * sizeof(struct usb_endpoint_descriptor);
                           as->endpoint = malloc(epsize);
                           memset(as->endpoint, 0, epsize);
                        }

                        // Load endpoints
                        for(k = 0; k < as->bNumEndpoints; ++k) {
                           struct usb_endpoint_descriptor* endpoint = &as->endpoint[k];
                           int szlen = sizeof(struct usb_endpoint_descriptor);
                           if(szlen > it.len)
                              szlen = it.len;

                           // Read endpoint and apply conversion
                           memcpy(endpoint, it.val, szlen);
                           endpoint->wMaxPacketSize = ntohs(endpoint->wMaxPacketSize);
                           iter_next(&it);

                           // Null extra descriptors.
                           endpoint->extralen = 0;
                           endpoint->extra = NULL;
                        }

                        // Read extra interface descriptors
                        as->extralen = as_int(it.val, it.len);
                        iter_next(&it);

                        if(as->extralen > 0){
                            as->extra = malloc(as->extralen);

                            int szlen = as->extralen;
                            if(szlen > it.len)
                                szlen = it.len;

                            memcpy(as->extra, it.val, szlen);
                            iter_next(&it);
                        }
                        else
                            as->extra = NULL;
                     }
                  }
               }

               //log_msg("Bus %s Device %s: ID %04x:%04x", rbus->dirname, dev->filename, dev->descriptor.idVendor, dev->descriptor.idProduct);
            }

            // Free unused devices
            while(dev->next != NULL) {
               struct usb_device* ddev = dev->next;
               debug_msg("deleting device %03d", ddev->devnum);
               dev->next = ddev->next;
               free(ddev);
            }

         }
         else {
            debug_msg("unexpected item identifier 0x%02x", it.type);
            iter_next(&it);
         }
      }

      // Deallocate unnecessary busses
      while(rbus->next != NULL) {
         debug_msg("deleting bus %03d", rbus->next->location);
         struct usb_bus* bus = rbus->next;
         rbus->next = bus->next;
      }

      // Save busses
      if(__remote_bus == NULL) {
         __orig_bus = usb_busses;
         debug_msg("overriding global usb_busses from %p to %p", usb_busses, vbus.next);
      }

      __remote_bus = vbus.next;
      usb_busses = __remote_bus;
   }

   // Return remote result
   pkt_release();
   debug_msg("returned %d", res);
   return res;
}