Skip to content

Commit

Permalink
vhci, let a webcam with IAD be detected as COMPOSITE
Browse files Browse the repository at this point in the history
A device with IAD(such as MS LifeCam) can be detected correctly by
replying USB/COMPOSITE as a compatible ID. But it's still not
working.(Camera app generates an error.)

Code beautify progressed
- "SerialNo" and "addr" are integrated into "port"
- Introduce wudev(windows specific structure for usbip userspace udev)
  • Loading branch information
cezanne committed Jan 29, 2019
1 parent ccbd1a0 commit 393ac6a
Show file tree
Hide file tree
Showing 13 changed files with 219 additions and 144 deletions.
2 changes: 1 addition & 1 deletion driver/vhci/vhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ vhci_cleanup(__in PDEVICE_OBJECT devobj, __in PIRP irp)
vpdo->fo = NULL;
irpstack->FileObject->FsContext = NULL;
if (vpdo->Present)
vhci_unplug_dev(vpdo->SerialNo, vhub);
vhci_unplug_dev(vpdo->port, vhub);
}
status = STATUS_SUCCESS;
irp->IoStatus.Information = 0;
Expand Down
5 changes: 2 additions & 3 deletions driver/vhci/vhci_dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,8 @@ typedef struct
// The array itself also null terminated
USHORT vendor, product, revision;
UCHAR usbclass, subclass, protocol, inum;

// Unique serial number of the device on the bus
ULONG SerialNo;
// unique port number of the device on the bus
ULONG port;

// Link point to hold all the vpdos for a single bus together
LIST_ENTRY Link;
Expand Down
16 changes: 8 additions & 8 deletions driver/vhci/vhci_plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,23 @@ vhci_init_vpdo(pusbip_vpdo_dev_t vpdo);
PAGEABLE NTSTATUS
vhci_plugin_dev(ioctl_usbip_vhci_plugin *plugin, pusbip_vhub_dev_t vhub, PFILE_OBJECT fo)
{
PDEVICE_OBJECT devobj;
pusbip_vpdo_dev_t vpdo, devpdo_old;
NTSTATUS status;
PLIST_ENTRY entry;
PDEVICE_OBJECT devobj;
pusbip_vpdo_dev_t vpdo, devpdo_old;
PLIST_ENTRY entry;
NTSTATUS status;

PAGED_CODE();

DBGI(DBG_PNP, "Exposing vpdo: addr: %d, vendor:product: %04x:%04x\n", plugin->addr, plugin->vendor, plugin->product);
DBGI(DBG_IOCTL, "Plugin vpdo: port: %hhd, vendor:product: %04hx:%04hx\n", plugin->port, plugin->vendor, plugin->product);

if (plugin->addr <= 0)
if (plugin->port <= 0)
return STATUS_INVALID_PARAMETER;

ExAcquireFastMutex(&vhub->Mutex);

for (entry = vhub->head_vpdo.Flink; entry != &vhub->head_vpdo; entry = entry->Flink) {
vpdo = CONTAINING_RECORD(entry, usbip_vpdo_dev_t, Link);
if ((ULONG)plugin->addr == vpdo->SerialNo &&
if ((ULONG)plugin->port == vpdo->port &&
vpdo->common.DevicePnPState != SurpriseRemovePending) {
ExReleaseFastMutex(&vhub->Mutex);
return STATUS_INVALID_PARAMETER;
Expand Down Expand Up @@ -84,7 +84,7 @@ vhci_plugin_dev(ioctl_usbip_vhci_plugin *plugin, pusbip_vhub_dev_t vhub, PFILE_O
IoDeleteDevice(devobj);
return STATUS_INVALID_PARAMETER;
}
vpdo->SerialNo = plugin->addr;
vpdo->port = plugin->port;
vpdo->fo = fo;
vpdo->devid = plugin->devid;
vpdo->speed = plugin->speed;
Expand Down
38 changes: 18 additions & 20 deletions driver/vhci/vhci_pnp.c
Original file line number Diff line number Diff line change
Expand Up @@ -729,44 +729,42 @@ vhci_get_ports_status(ioctl_usbip_vhci_get_ports_status *st, pusbip_vhub_dev_t v

for (entry = vhub->head_vpdo.Flink; entry != &vhub->head_vpdo; entry = entry->Flink) {
vpdo = CONTAINING_RECORD (entry, usbip_vpdo_dev_t, Link);
if (vpdo->SerialNo > 127 || vpdo->SerialNo == 0) {
if (vpdo->port > 127 || vpdo->port == 0) {
DBGE(DBG_PNP, "strange error");
}
if (st->u.max_used_port < (char)vpdo->SerialNo)
st->u.max_used_port = (char)vpdo->SerialNo;
st->u.port_status[vpdo->SerialNo] = 1;
if (st->u.max_used_port < (char)vpdo->port)
st->u.max_used_port = (char)vpdo->port;
st->u.port_status[vpdo->port] = 1;
}
ExReleaseFastMutex(&vhub->Mutex);
*info = sizeof(*st);
return STATUS_SUCCESS;
}

PAGEABLE NTSTATUS
vhci_unplug_dev(int addr, pusbip_vhub_dev_t vhub)
vhci_unplug_dev(ULONG port, pusbip_vhub_dev_t vhub)
{
pusbip_vpdo_dev_t vpdo;
PLIST_ENTRY entry;
int found = 0, all;

PAGED_CODE();

if (addr < 0 || addr > 127)
if (port > 127)
return STATUS_INVALID_PARAMETER;

all = (0 == addr);
all = (0 == port);

ExAcquireFastMutex(&vhub->Mutex);

if (all) {
DBGI(DBG_PNP, "Plugging out all the devices!\n");
} else {
DBGI(DBG_PNP, "Plugging out single device: %d\n", addr);
DBGI(DBG_PNP, "Plugging out single device: port: %u\n", port);
}

if (vhub->n_vpdos == 0) {
//
// We got a 2nd plugout...somebody in user space isn't playing nice!!!
//
DBGW(DBG_PNP, "BAD BAD BAD...2 removes!!! Send only one!\n");
ExReleaseFastMutex(&vhub->Mutex);
return STATUS_NO_SUCH_DEVICE;
Expand All @@ -775,10 +773,10 @@ vhci_unplug_dev(int addr, pusbip_vhub_dev_t vhub)
for (entry = vhub->head_vpdo.Flink; entry != &vhub->head_vpdo; entry = entry->Flink) {
vpdo = CONTAINING_RECORD(entry, usbip_vpdo_dev_t, Link);

DBGI(DBG_PNP, "found device %d\n", vpdo->SerialNo);
DBGI(DBG_PNP, "found device: port: %d\n", vpdo->port);

if (all || addr == (int)vpdo->SerialNo) {
DBGI(DBG_PNP, "Plugging out %d\n", vpdo->SerialNo);
if (all || port == vpdo->port) {
DBGI(DBG_PNP, "Plugging out: port: %u\n", vpdo->port);
vpdo->Present = FALSE;
complete_pending_read_irp(vpdo);
found = 1;
Expand Down Expand Up @@ -806,7 +804,7 @@ vhci_unplug_dev(int addr, pusbip_vhub_dev_t vhub)
}
ExReleaseFastMutex(&vhub->Mutex);

DBGI(DBG_PNP, "Device %d plug out finished\n", addr);
DBGI(DBG_PNP, "Device %u plug out finished\n", port);
return STATUS_SUCCESS;
}

Expand All @@ -822,14 +820,14 @@ vhci_eject_device(PUSBIP_VHCI_EJECT_HARDWARE Eject, pusbip_vhub_dev_t vhub)

PAGED_CODE ();

ejectAll = (0 == Eject->SerialNo);
ejectAll = (0 == Eject->port);

ExAcquireFastMutex(&vhub->Mutex);

if (ejectAll) {
DBGI(DBG_PNP, "Ejecting all the vpdo's!\n");
} else {
DBGI(DBG_PNP, "Ejecting %d\n", Eject->SerialNo);
DBGI(DBG_PNP, "Ejecting: port: %u\n", Eject->port);
}

if (vhub->n_vpdos == 0) {
Expand All @@ -843,10 +841,10 @@ vhci_eject_device(PUSBIP_VHCI_EJECT_HARDWARE Eject, pusbip_vhub_dev_t vhub)
for (entry = vhub->head_vpdo.Flink; entry != &vhub->head_vpdo; entry = entry->Flink) {
vpdo = CONTAINING_RECORD(entry, usbip_vpdo_dev_t, Link);

DBGI(DBG_PNP, "found device %d\n", vpdo->SerialNo);
DBGI(DBG_PNP, "found device: %u\n", vpdo->port);

if (ejectAll || Eject->SerialNo == vpdo->SerialNo) {
DBGI(DBG_PNP, "Ejected %d\n", vpdo->SerialNo);
if (ejectAll || Eject->port == vpdo->port) {
DBGI(DBG_PNP, "Ejected: %u\n", vpdo->port);
found = TRUE;
IoRequestDeviceEject(vpdo->common.Self);
if (!ejectAll) {
Expand All @@ -860,7 +858,7 @@ vhci_eject_device(PUSBIP_VHCI_EJECT_HARDWARE Eject, pusbip_vhub_dev_t vhub)
return STATUS_SUCCESS;
}

DBGW(DBG_PNP, "Device %d is not present\n", Eject->SerialNo);
DBGW(DBG_PNP, "Device %u is not present\n", Eject->port);

return STATUS_INVALID_PARAMETER;
}
2 changes: 1 addition & 1 deletion driver/vhci/vhci_pnp.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
(_Data_)->common.DevicePnPState = (_Data_)->common.PreviousPnPState;

PAGEABLE NTSTATUS
vhci_unplug_dev(int addr, pusbip_vhub_dev_t vhub);
vhci_unplug_dev(ULONG port, pusbip_vhub_dev_t vhub);
17 changes: 10 additions & 7 deletions driver/vhci/vhci_vpdo.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#define USBIP_DEVICE_DESC L"USB Device Over IP"
#define USBIP_DEVICE_LOCINFO L"on USB/IP VHCI"

/* Device with IAD(Interface Association Descriptor) */
#define IS_IAD_DEVICE(vpdo) ((vpdo)->usbclass == 0xef && (vpdo)->subclass == 0x02 && (vpdo)->protocol == 0x01)

extern PAGEABLE NTSTATUS
destroy_vpdo(pusbip_vpdo_dev_t vpdo);

Expand Down Expand Up @@ -193,11 +196,11 @@ vhci_QueryDeviceCaps_vpdo(pusbip_vpdo_dev_t vpdo, PIRP Irp)
// does not support an address, the bus driver leaves this
// member at its default value of 0xFFFFFFFF. In this example
// the location address is same as instance id.
deviceCapabilities->Address = vpdo->SerialNo;
deviceCapabilities->Address = vpdo->port;

// UINumber specifies a number associated with the device that can
// be displayed in the user interface.
deviceCapabilities->UINumber = vpdo->SerialNo;
deviceCapabilities->UINumber = vpdo->port;

return STATUS_SUCCESS;
}
Expand Down Expand Up @@ -225,7 +228,7 @@ setup_vpdo_inst_id(pusbip_vpdo_dev_t vpdo, PIRP irp)
if (id_inst == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlStringCchPrintfW(id_inst, 5, L"%04hx", vpdo->SerialNo);
RtlStringCchPrintfW(id_inst, 5, L"%04hx", vpdo->port);
irp->IoStatus.Information = (ULONG_PTR)id_inst;
return STATUS_SUCCESS;
}
Expand Down Expand Up @@ -255,10 +258,10 @@ setup_vpdo_compat_ids(pusbip_vpdo_dev_t vpdo, PIRP irp)
if (ids_compat == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlStringCchPrintfW(ids_compat, 33, L"USB\\Class_%02x&SubClass_%02x&Prot_%02x", vpdo->usbclass, vpdo->subclass, vpdo->protocol);
RtlStringCchPrintfW(ids_compat + 33, 25, L"USB\\Class_%02x&SubClass_%02x", vpdo->usbclass, vpdo->subclass);
RtlStringCchPrintfW(ids_compat + 58, 13, L"USB\\Class_%02x", vpdo->usbclass);
if (vpdo->inum > 1) {
RtlStringCchPrintfW(ids_compat, 33, L"USB\\Class_%02hhx&SubClass_%02hhx&Prot_%02hhx", vpdo->usbclass, vpdo->subclass, vpdo->protocol);
RtlStringCchPrintfW(ids_compat + 33, 25, L"USB\\Class_%02hhx&SubClass_%02hhx", vpdo->usbclass, vpdo->subclass);
RtlStringCchPrintfW(ids_compat + 58, 13, L"USB\\Class_%02hhx", vpdo->usbclass);
if (vpdo->inum > 1 || IS_IAD_DEVICE(vpdo)) {
RtlStringCchCopyW(ids_compat + 71, 14, L"USB\\COMPOSITE");
ids_compat[85] = L'\0';
}
Expand Down
32 changes: 16 additions & 16 deletions include/usbip_vhci_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,20 @@ DEFINE_GUID(USBIP_NOTIFY_DEVICE_ARRIVAL_EVENT,

typedef struct _ioctl_usbip_vhci_plugin
{
unsigned int devid;
/* 4 bytes */
unsigned short vendor;
unsigned short product;
/* 8 bytes */
unsigned short version;
unsigned char speed;
unsigned char inum;
/* 12 bytes */
unsigned char class;
unsigned char subclass;
unsigned char protocol;
signed char addr; /* then it can not be bigger then 127 */
/* 16 bytes */
unsigned int devid;

unsigned short vendor;
unsigned short product;

unsigned short version;
unsigned char speed;
unsigned char inum;

unsigned char class;
unsigned char subclass;
unsigned char protocol;

signed char port;
} ioctl_usbip_vhci_plugin;

typedef struct _ioctl_usbip_vhci_get_ports_status
Expand All @@ -93,7 +93,7 @@ typedef struct _USBIP_VHCI_EJECT_HARDWARE
// sizeof (struct _EJECT_HARDWARE)
ULONG Size;

// Serial number of the device to be ejected
ULONG SerialNo;
// port number of the device to be ejected
ULONG port;
ULONG Reserved[2];
} USBIP_VHCI_EJECT_HARDWARE, *PUSBIP_VHCI_EJECT_HARDWARE;
2 changes: 2 additions & 0 deletions userspace/src/usbip/usbip.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,14 @@
<ClCompile Include="usbip_list.c" />
<ClCompile Include="usbip_list_local.c" />
<ClCompile Include="usbip_list_remote.c" />
<ClCompile Include="usbip_wudev.c" />
<ClCompile Include="usbip_unbind.c" />
<ClCompile Include="usbip_vhci.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\config.h" />
<ClInclude Include="usbip.h" />
<ClInclude Include="usbip_wudev.h" />
<ClInclude Include="usbip_vhci.h" />
</ItemGroup>
<ItemGroup>
Expand Down
Loading

0 comments on commit 393ac6a

Please sign in to comment.