void UsbDeviceList::LogFilterField(LPCWSTR name, LPCINTERFACE_FILTER_FIELD field) { if (field->value == USB_NO_INFO) { IFACEFILTER_MSG((TEXT("USBKWrapperDrv: %s == <any>\r\n"), name)); } else if (field->match) { IFACEFILTER_MSG((TEXT("USBKWrapperDrv: %s == 0x%x\r\n"), name, field->value)); } else { IFACEFILTER_MSG((TEXT("USBKWrapperDrv: %s != 0x%x\r\n"), name, field->value)); } }
void UsbDeviceList::AddInterfaceFilter(LPCWSTR name, LPCWSTR value) { // Filter name must be unique PFILTER_NODE next = mInterfaceFilters; while (next) { if (wcscmp(name, next->filter.name) == 0) { IFACEFILTER_MSG((TEXT("USBKWrapperDrv: Ignoring duplicate interface filter %s\r\n"), name)); return; } next = next->next; } // Prepare new filter PFILTER_NODE newFilter = new (std::nothrow) FILTER_NODE; if (!newFilter) { ERROR_MSG((TEXT("USBKWrapperDrv!UsbDeviceList::AddInterfaceFilter() - Out of memory allocating new filter node\r\n"))); return; } newFilter->filter.name = new (std::nothrow) WCHAR[wcslen(name) + 1]; if (!newFilter->filter.name) { ERROR_MSG((TEXT("USBKWrapperDrv!UsbDeviceList::AddInterfaceFilter() - Out of memory allocating filter name\r\n"))); delete newFilter; return; } wcscpy(newFilter->filter.name, name); // Parse filter string if (!ParseFilterString(newFilter->filter, value)) { IFACEFILTER_MSG((TEXT("USBKWrapperDrv: Discarding invalid interface filter %s: %s\r\n"), name, value)); // Destroy filter delete[] newFilter->filter.name; delete newFilter; return; } // Insert filter into the correct position in the list (dependent on priority) if (!mInterfaceFilters || newFilter->filter.priority <= mInterfaceFilters->filter.priority) { // Insert at the head newFilter->next = mInterfaceFilters; mInterfaceFilters = newFilter; } else { next = mInterfaceFilters; while (next) { if (!next->next || newFilter->filter.priority <= next->next->filter.priority) { // Insert after this element (which may be the tail) newFilter->next = next->next; next->next = newFilter; break; } next = next->next; } } }
void UsbDeviceList::LogFilterFlag(LPCWSTR name, BOOL flag) { // Only log the flags that are set explicitly. if (flag) { IFACEFILTER_MSG((TEXT("USBKWrapperDrv: %s\r\n"), name)); } }
void UsbDeviceList::LogFilter(LPCWSTR message, LPCINTERFACE_FILTER filter) { IFACEFILTER_MSG((TEXT("%s %s:\r\n"), message, filter->name)); if (filter->priority == MAXDWORD) { IFACEFILTER_MSG((TEXT("USBKWrapperDrv: priority: <none>\r\n"))); } else { IFACEFILTER_MSG((TEXT("USBKWrapperDrv: priority: %u\r\n"), filter->priority)); } LogFilterField(TEXT("bInterfaceClass"), &filter->bInterfaceClass); LogFilterField(TEXT("bInterfaceSubClass"), &filter->bInterfaceSubClass); LogFilterField(TEXT("bInterfaceProtocol"), &filter->bInterfaceProtocol); LogFilterField(TEXT("idVendor"), &filter->idVendor); LogFilterField(TEXT("idProduct"), &filter->idProduct); LogFilterFlag(TEXT("NO_ATTACH"), filter->noAttach); }
void UsbDeviceList::LogFilter(LPCWSTR message, LPCINTERFACE_FILTER filter) { IFACEFILTER_MSG((TEXT("%s %s:\r\n"), message, filter->name)); LogFilterField(TEXT("bInterfaceClass"), &filter->bInterfaceClass); LogFilterField(TEXT("bInterfaceSubClass"), &filter->bInterfaceSubClass); LogFilterField(TEXT("bInterfaceProtocol"), &filter->bInterfaceProtocol); LogFilterField(TEXT("idVendor"), &filter->idVendor); LogFilterField(TEXT("idProduct"), &filter->idProduct); LogFilterFlag(TEXT("NO_ATTACH"), filter->noAttach); }
BOOL UsbDeviceList::AttachDevice( USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs, LPCUSB_INTERFACE lpInterface, LPCWSTR szUniqueDriverId, LPBOOL fAcceptControl, LPCUSB_DRIVER_SETTINGS lpDriverSettings, DWORD dwUnused) { unsigned char bus = 0, address = 0; unsigned long session_id = 0; MutexLocker lock(mMutex); (void) szUniqueDriverId; // In future allowing some filtering based on lpDriverSettings // here could be useful. (void) lpDriverSettings; (void) dwUnused; // Default to accepting control of device, until we find a reason not to. *fAcceptControl = TRUE; LPCUSB_DEVICE device = lpUsbFuncs->lpGetDeviceInfo(hDevice); // Retrieve interface filter list from registry if not already done so FetchInterfaceFilters(lpUsbFuncs, szUniqueDriverId); // If we're attaching for an interface only, then refuse if the interface is // in our filter list. Else, if we're attaching for a device only then refuse if // we are already attached (we may be trying to find other drivers). if (lpInterface) { DWORD index; if (FindFilterForInterface(device, lpInterface, &index)) { IFACEFILTER_MSG((TEXT("USBKWrapperDrv: Interface %i matches filter %s, not attaching\r\n"), lpInterface->Descriptor.bInterfaceNumber, mInterfaceFilters[index].name)); (*fAcceptControl) = FALSE; return FALSE; } } else { for (PtrArray<UsbDevice>::iterator it = mDevices.begin(); it != mDevices.end(); ++it) { if ((*it)->IsSameDevice(hDevice)) { WARN_MSG((TEXT("USBKWrapperDrv: Already attached to device, not attaching again\r\n"))); (*fAcceptControl) = FALSE; return FALSE; } } } // If we're attaching for the entire device, locate any interface filters // matching the interfaces of this device. // // If any matching filter specifies NO_ATTACH, we refuse to accept control // of the device. We only match one filter to an interface. If multiple // filters match, only the first shall be used. BOOL filterMatches = FALSE; ArrayAutoPtr<DWORD> filters; if (!lpInterface && mNumInterfaceFilters > 0) { filters = new (std::nothrow) DWORD[device->lpActiveConfig->dwNumInterfaces]; if (!filters.Get()) { ERROR_MSG((TEXT("USBKWrapperDrv!UsbDeviceList::AttachDevice") TEXT(" - out of memory allocating filter match list"))); *fAcceptControl = FALSE; return FALSE; } for (DWORD i = 0; i < device->lpActiveConfig->dwNumInterfaces && *fAcceptControl; i++) { DWORD index; if (FindFilterForInterface(device, &device->lpActiveConfig->lpInterfaces[i], &index)) { filters.Set(i, index); filterMatches = TRUE; if (mInterfaceFilters[index].noAttach) { IFACEFILTER_MSG((TEXT("USBKWrapperDrv: Interface %u matches filter %s") TEXT(", not accepting device control\r\n"), device->lpActiveConfig->lpInterfaces[i].Descriptor.bInterfaceNumber, mInterfaceFilters[index].name)); *fAcceptControl = FALSE; } } else { filters.Set(i, mNumInterfaceFilters); } } } // If we're not accepting control, finish now if (!*fAcceptControl) { return FALSE; } // Allocate a fake bus and address for this device // as WinCE doesn't expose the bus and address to // USB Function Drivers. if (!mBusAllocator.Alloc(bus, address, session_id)) { ERROR_MSG((TEXT("USBKWrapperDrv!UsbDeviceList::AttachDevice") TEXT(" - failed to allocate fake USB bus and adress for handle 0x%08x\r\n"), hDevice)); *fAcceptControl = FALSE; return FALSE; } std::auto_ptr<UsbDevice> ptr ( new (std::nothrow) UsbDevice(bus, address, session_id)); if (!ptr.get()) { mBusAllocator.Free(bus, address, session_id); ERROR_MSG((TEXT("USBKWrapperDrv!UsbDeviceList::AttachDevice") TEXT(" - failed to allocate new USB device for handle 0x%08x\r\n"), hDevice)); *fAcceptControl = FALSE; return FALSE; } if (!ptr.get()->Init(hDevice, lpUsbFuncs, lpInterface)) { ERROR_MSG((TEXT("USBKWrapperDrv!UsbDeviceList::AttachDevice") TEXT(" - failed to initialise new USB device for handle 0x%08x\r\n"), hDevice)); *fAcceptControl = FALSE; return FALSE; } if (!mDevices.insert(ptr.get())) { ERROR_MSG((TEXT("USBKWrapperDrv!UsbDeviceList::AttachDevice") TEXT(" - failed to store new USB device for handle 0x%08x\r\n"), hDevice)); *fAcceptControl = FALSE; return FALSE; } // Release any interfaces matching filters if (filterMatches) { // Try to release any interfaces that match our filters (if we have any) BOOL failedToAttach = FALSE; BOOL attachSuccesful = FALSE; for (DWORD i = 0; i < device->lpActiveConfig->dwNumInterfaces && !failedToAttach; i++) { if (filters.Get(i) < mNumInterfaceFilters) { UCHAR bInterfaceNumber = device->lpActiveConfig->lpInterfaces[i].Descriptor.bInterfaceNumber; IFACEFILTER_MSG((TEXT("USBKWrapperDrv: Interface %u matches filter %s") TEXT(", attaching kernel driver\r\n"), bInterfaceNumber, mInterfaceFilters[filters.Get(i)].name)); if (ptr.get()->AttachKernelDriverForInterface(bInterfaceNumber)) { attachSuccesful = TRUE; } else if (!attachSuccesful) { // Only resort to finding a driver for the entire device, if we have // not already attached drivers to other interfaces. failedToAttach = TRUE; } } } if (failedToAttach) { // Try to find a driver for the entire device. We will release all of our interfaces, // but still reserve the right to send arbitrary control transfers. IFACEFILTER_MSG((TEXT("USBKWrapperDrv: Attaching kernel driver for entire device\r\n"))); if (!ptr.get()->AttachKernelDriverForDevice()) { // There really is no other driver willing to control this device! IFACEFILTER_MSG((TEXT("USBKWrapperDrv: Unable to attach kernel driver for entire ") TEXT("device (error %u), retaining control\r\n"), GetLastError())); } } } ptr.release(); return TRUE; }
void UsbDeviceList::AddInterfaceFilter(LPCWSTR name, LPCWSTR value) { // Filter name must be unique for (DWORD i = 0; i < mNumInterfaceFilters; i++) { if (wcscmp(name, mInterfaceFilters[i].name) == 0) { IFACEFILTER_MSG((TEXT("USBKWrapperDrv: Ignoring duplicate interface filter %s\r\n"), name)); return; } } // Parse filter string "bInterfaceClass:bInterfaceSubclass:bInterfaceProtocol" // Any field can be '*', represent this "dont-care" as USB_NO_INFO. INTERFACE_FILTER_FIELD bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol; DWORD nextOffset, result; result = FindNextInterfaceFilterField(value, 0, &nextOffset, &bInterfaceClass); result |= FindNextInterfaceFilterField(value, nextOffset, &nextOffset, &bInterfaceSubClass); result |= FindNextInterfaceFilterField(value, nextOffset, &nextOffset, &bInterfaceProtocol); if (result) { IFACEFILTER_MSG((TEXT("USBKWrapperDrv: Parse error for interface filter %s: %s\r\n"), name, value)); return; } // Now check for optional idVendor/idProduct fields (initialised by FindNextInterfaceFilterToken()) INTERFACE_FILTER_FIELD idVendor, idProduct; FindNextInterfaceFilterField(value, nextOffset, &nextOffset, &idVendor); FindNextInterfaceFilterField(value, nextOffset, &nextOffset, &idProduct); PWCHAR filterName = (PWCHAR) malloc(sizeof(WCHAR)*(wcslen(name)+1));; if (!filterName) { ERROR_MSG((TEXT("USBKWrapperDrv!UsbDeviceList::AddInterfaceFilter() - Out of memory allocating filter name\r\n"))); return; } wcscpy(filterName, name); // Finally, check for any optional flags (we can switch to a more advanced // flag parsing strategy if and when we add more flags in the future). BOOL noAttach = FALSE; if (wcsstr(value, L";NO_ATTACH") != NULL) { noAttach = TRUE; } INTERFACE_FILTER* newFilterList = (INTERFACE_FILTER*) realloc(mInterfaceFilters, sizeof(INTERFACE_FILTER)*(mNumInterfaceFilters+1)); if (!newFilterList) { ERROR_MSG((TEXT("USBKWrapperDrv!UsbDeviceList::AddInterfaceFilter() - Out of memory reallocating filter list\r\n"))); free(filterName); return; } // Append filter to list mInterfaceFilters = newFilterList; mInterfaceFilters[mNumInterfaceFilters].name = filterName; mInterfaceFilters[mNumInterfaceFilters].bInterfaceClass = bInterfaceClass; mInterfaceFilters[mNumInterfaceFilters].bInterfaceSubClass = bInterfaceSubClass; mInterfaceFilters[mNumInterfaceFilters].bInterfaceProtocol = bInterfaceProtocol; mInterfaceFilters[mNumInterfaceFilters].idVendor = idVendor; mInterfaceFilters[mNumInterfaceFilters].idProduct = idProduct; mInterfaceFilters[mNumInterfaceFilters].noAttach = noAttach; LogFilter(TEXT("USBKWrapperDrv: Added interface filter"), &mInterfaceFilters[mNumInterfaceFilters]); mNumInterfaceFilters++; }