/* * Open a directory. * Params: * state->ebx - address of user string containing path of directory to open * state->ecx - length of path * * Returns: a file descriptor (>= 0) if successful, * or an error code (< 0) if unsuccessful */ static int Sys_OpenDirectory(struct Interrupt_State *state) { char *path; struct File *file; int rc = 0; rc = get_path_from_registers(state->ebx, state->ecx, &path); if(rc != 0) { return rc; } rc = next_descriptor(); if(rc < 0) { return rc; } Enable_Interrupts(); // duped from schulman rc = Open_Directory(path, &file); Disable_Interrupts(); Free(path); if(rc >= 0) { return add_file_to_descriptor_table(file); } else { return rc; } }
static int add_file_to_descriptor_table(struct File *file) { int descriptor = next_descriptor(); if(descriptor >= 0) { g_currentThread->userContext->file_descriptor_table[descriptor] = file; } return descriptor; }
/* * Including ones with alternate settings. * Additionally it checks the descriptor's correctness. * Descriptors often follow each other in a rather chaotical way. * * Device can have interfaces with chaotical numbers. * For example, one real device has four interfaces with numbers #0, #2, #3, #8. */ int get_total_interfaces(const struct usb_config_descriptor *d) { struct usb_interface_descriptor *id = 0; int total_len = 0; int len = 0; int ifcnt = 0; int ok = 0; if (!d) { return -1; } ok = d->bLength == USB_DT_CONFIG_SIZE && d->bDescriptorType == USB_DT_CONFIG && d->wTotalLength > d->bLength; if (!ok) { return -2; } total_len = d->wTotalLength; // FIXME: le16_to_cpu len = d->bLength; id = first_interface(d, 0); while (((char*)id - (char*)d) < total_len) { int ifsz = get_interface_size(id); if (ifsz) { ++ifcnt; len += ifsz; id = next_interface(id); } else { // not an interface len += id->bLength; id = next_descriptor(id); } } if (ifcnt < d->bNumInterfaces) { // yes, not !=, Logitech C500 fails otherwise return -3; } if (len != d->wTotalLength) { return -4; } return ((char*)id - (char*)d) == total_len ? ifcnt : -5; }
struct usb_interface_descriptor *find_interface( const struct usb_config_descriptor *d, int num, int altnum) { int cnt = get_total_interfaces(d); struct usb_interface_descriptor *iface = cnt > 0 ? first_interface(d, 0) : 0; int i = 0; for (i = 0; i < cnt && iface;) { if (!is_interface(iface)) { iface = next_descriptor(iface); } else if (iface->bInterfaceNumber == num && iface->bAlternateSetting == altnum) { return iface; } else { iface = next_interface(iface); ++i; } } return 0; }