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++; }
void UsbDeviceList::FetchInterfaceFilters(LPCUSB_FUNCS lpUsbFuncs, LPCWSTR szUniqueDriverId) { HKEY key; LONG result; DWORD numValues = 0, maxNameLen = 0, maxValueLen = 0; DWORD valueType; PWCHAR nameBuf; PBYTE valueBuf; // We do not support dynamic updating of the filter list if (mInterfaceFilters) { return; } key = lpUsbFuncs->lpOpenClientRegistyKey(szUniqueDriverId); if (!key) { ERROR_MSG((TEXT("USBKWrapperDrv!UsbDeviceList::FetchInterfaceFilters() - Failed to open client registry key\r\n"))); return; } result = RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, &numValues, &maxNameLen, &maxValueLen, NULL, NULL); if (result != ERROR_SUCCESS) { ERROR_MSG((TEXT("USBKWrapperDrv!UsbDeviceList::FetchInterfaceFilters() - Failed to query key info: error %i\r\n"), result)); RegCloseKey(key); return; } nameBuf = new (std::nothrow) WCHAR[maxNameLen+1]; valueBuf = new (std::nothrow) BYTE[maxValueLen]; if (!nameBuf || !valueBuf) { ERROR_MSG((TEXT("USBKWrapperDrv!UsbDeviceList::FetchInterfaceFilters() - Out of memory allocating buffers\r\n"))); delete[] nameBuf; delete[] valueBuf; RegCloseKey(key); return; } for (DWORD index = 0; index < numValues && result == ERROR_SUCCESS; index++) { DWORD nameBufSize = maxNameLen + 1; DWORD valueBufSize = maxValueLen; result = RegEnumValue(key, index, nameBuf, &nameBufSize, NULL, &valueType, valueBuf, &valueBufSize); if (result == ERROR_SUCCESS) { // Pay attention only to unicode strings (REG_SZ) whose name has the // InterfaceFilter_ prefix if (nameBufSize > 16 && wcsncmp(nameBuf, TEXT("InterfaceFilter_"), 16) == 0 && valueType == REG_SZ) { AddInterfaceFilter(&nameBuf[16], (LPCWSTR) valueBuf); } } } // Log out the interface filters we have, in priority order PFILTER_NODE next = mInterfaceFilters; while(next) { LogFilter(TEXT("USBKWrapperDrv: Added interface filter"), &next->filter); next = next->next; } delete[] nameBuf; delete[] valueBuf; RegCloseKey(key); }