예제 #1
0
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));
	}
}
예제 #2
0
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;
		}
	}
}
예제 #3
0
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));
	}
}
예제 #4
0
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);
}
예제 #5
0
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);
}
예제 #6
0
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;
}
예제 #7
0
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++;
}