743 lines
17 KiB
C
743 lines
17 KiB
C
/*++
|
|
|
|
Copyright (c) 1998 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
USBHUBF.C
|
|
|
|
Abstract:
|
|
|
|
Environment:
|
|
|
|
kernel mode only
|
|
|
|
Notes:
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
|
|
--*/
|
|
|
|
|
|
#include <wdm.h>
|
|
#include "stdarg.h"
|
|
#include "stdio.h"
|
|
|
|
#include "dbci.h"
|
|
#include "dbclass.h"
|
|
#include "dbfilter.h"
|
|
|
|
#include "usbioctl.h"
|
|
|
|
//
|
|
// Registry keys
|
|
//
|
|
|
|
#define DBCLASS_HUB_IS_ACPI_DBC 0x00000001
|
|
#define DBCLASS_HUB_IS_USB_DBC 0x00000002
|
|
|
|
extern LONG DBCLASS_AcpiDBCHubParentPort;
|
|
|
|
|
|
NTSTATUS
|
|
DBCLASS_UsbhubQBusRelationsComplete(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp,
|
|
IN PVOID Context
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - a pointer to the device object
|
|
|
|
Irp - a pointer to the irp
|
|
|
|
Context - NULL ptr
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVICE_RELATIONS deviceRelations;
|
|
ULONG i;
|
|
PDEVICE_OBJECT busFilterMdo = Context;
|
|
PDEVICE_EXTENSION deviceExtension;
|
|
PDEVICE_OBJECT mdoUSB;
|
|
PDBC_CONTEXT dbcContext;
|
|
|
|
deviceExtension = busFilterMdo->DeviceExtension;
|
|
deviceRelations = (PDEVICE_RELATIONS) Irp->IoStatus.Information;
|
|
|
|
LOGENTRY(LOG_MISC, 'UQBR', busFilterMdo, 0, deviceRelations);
|
|
|
|
if (deviceRelations == NULL) {
|
|
LOGENTRY(LOG_MISC, 'UQBn', busFilterMdo, 0, deviceRelations);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
// try to find the DBC controller associated with this hub
|
|
//
|
|
// Since the filter is loaded for every hub we need to see
|
|
// if this hub is part of a DBC subsystem
|
|
|
|
|
|
dbcContext = deviceExtension->DbcContext;
|
|
|
|
if (dbcContext == NULL) {
|
|
DBCLASS_KdPrint((1, "'>QBR USB, HUB NOT DBC\n"));
|
|
// no context means the hub is not part of DBC
|
|
LOGENTRY(LOG_MISC, 'hQBi', 0, 0, 0);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
for (i=0; i< deviceRelations->Count; i++) {
|
|
|
|
DBCLASS_KdPrint((1, "'>QBR USB PDO[%d] %x\n", i,
|
|
deviceRelations->Objects[i]));
|
|
|
|
LOGENTRY(LOG_MISC, 'QBRd', deviceRelations->Objects[i], i, 0);
|
|
|
|
// hub is returning a PDO, see if we know
|
|
// about it
|
|
|
|
mdoUSB = DBCLASS_FindDevicePdo(deviceRelations->Objects[i]);
|
|
|
|
if (mdoUSB) {
|
|
// we know about this one,
|
|
// see if we can link it to a controller
|
|
PDEVICE_EXTENSION mdoUSBDeviceExtension;
|
|
|
|
mdoUSBDeviceExtension = mdoUSB->DeviceExtension;
|
|
mdoUSBDeviceExtension->DbcContext = dbcContext;
|
|
|
|
} else {
|
|
PDEVICE_OBJECT deviceFilterObject;
|
|
NTSTATUS ntStatus;
|
|
|
|
// don't know about it,
|
|
// create an MDO for this device
|
|
|
|
ntStatus = DBCLASS_CreateDeviceFilterObject(
|
|
deviceExtension->DriverObject,
|
|
&deviceFilterObject,
|
|
deviceRelations->Objects[i],
|
|
dbcContext,
|
|
DB_FDO_USB_DEVICE);
|
|
|
|
DBCLASS_KdPrint((1, "'>>QBR attaching to USB PDO[%d] %x\n", i,
|
|
deviceRelations->Objects[i]));
|
|
DBCLASS_KdPrint((1, "'(dbfilter)(bus)(USB) Create DO %x for USB PDO\n", deviceFilterObject));
|
|
|
|
}
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
DBCLASS_UsbhubBusFilterDispatch(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp,
|
|
PBOOLEAN Handled
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is a call to the root hub PDO
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - Device bay Filter FDO
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS
|
|
|
|
--*/
|
|
{
|
|
PIO_STACK_LOCATION irpStack;
|
|
NTSTATUS ntStatus;
|
|
PDEVICE_EXTENSION deviceExtension;
|
|
|
|
deviceExtension = DeviceObject->DeviceExtension;
|
|
ntStatus = Irp->IoStatus.Status;
|
|
*Handled = FALSE;
|
|
irpStack = IoGetCurrentIrpStackLocation (Irp);
|
|
|
|
LOGENTRY(LOG_MISC, 'HBf>', 0, DeviceObject, Irp);
|
|
DBCLASS_ASSERT(deviceExtension->FdoType == DB_FDO_USBHUB_BUS);
|
|
|
|
DBCLASS_KdPrint((2, "'(dbfilter)(bus)(USB)IRP_MJ_ (%08X) IRP_MN_ (%08X)\n",
|
|
irpStack->MajorFunction, irpStack->MinorFunction));
|
|
|
|
switch (irpStack->MajorFunction) {
|
|
|
|
case IRP_MJ_PNP:
|
|
switch (irpStack->MinorFunction) {
|
|
case IRP_MN_START_DEVICE:
|
|
DBCLASS_KdPrint((1, "'(dbfilter)(bus)(USB)IRP_MN_START_DEVICE\n"));
|
|
break;
|
|
|
|
case IRP_MN_STOP_DEVICE:
|
|
DBCLASS_KdPrint((1, "'(dbfilter)(bus)(USB)IRP_MN_STOP_DEVICE\n"));
|
|
break;
|
|
|
|
case IRP_MN_REMOVE_DEVICE:
|
|
DBCLASS_KdPrint((1, "'(dbfilter)(bus)(USB)IRP_MN_REMOVE_DEVICE\n"));
|
|
|
|
// detach from the usbhub FDO and delete our
|
|
// MDO
|
|
|
|
DBCLASS_RemoveBusFilterMDOFromList(DeviceObject);
|
|
|
|
IoDetachDevice(deviceExtension->TopOfStackDeviceObject);
|
|
|
|
IoDeleteDevice (DeviceObject);
|
|
DBCLASS_KdPrint((1, "'REMOVE DB Filter on USB HUB\n"));
|
|
|
|
break;
|
|
|
|
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
|
DBCLASS_KdPrint((1, "'(dbfilter)(bus)(USB)IRP_MN_QUERY_DEVICE_RELATIONS\n"));
|
|
|
|
//#if DBG
|
|
// DBCLASS_Get1394BayPortMapping(deviceExtension->DbcContext);
|
|
//#endif
|
|
|
|
//
|
|
// do the check for USB hubs that are part of a DBC
|
|
//
|
|
|
|
//
|
|
// Ask the hub if it has a DBC hanging on it
|
|
//
|
|
if (deviceExtension->DbcContext == NULL &&
|
|
DBCLASS_IsHubPartOfUSB_DBC(DeviceObject)) {
|
|
|
|
deviceExtension->DbcContext =
|
|
DBCLASS_FindControllerUSB(deviceExtension->DriverObject,
|
|
DeviceObject,
|
|
deviceExtension->PhysicalDeviceObject);
|
|
}
|
|
|
|
*Handled = TRUE;
|
|
|
|
if (irpStack->Parameters.QueryDeviceRelations.Type == BusRelations) {
|
|
|
|
DBCLASS_KdPrint((1,"'>>QBR USB BUS\n"));
|
|
IoCopyCurrentIrpStackLocationToNext(Irp);
|
|
|
|
// Set up a completion routine to handle marking the IRP.
|
|
IoSetCompletionRoutine(Irp,
|
|
DBCLASS_UsbhubQBusRelationsComplete,
|
|
DeviceObject,
|
|
TRUE,
|
|
TRUE,
|
|
TRUE);
|
|
} else {
|
|
IoSkipCurrentIrpStackLocation(Irp)
|
|
}
|
|
|
|
// Now Pass down the IRP
|
|
|
|
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
|
|
|
|
break;
|
|
} /* irpStack->MinorFunction */
|
|
break;
|
|
} /* irpStack->MajorFunction */
|
|
|
|
LOGENTRY(LOG_MISC, 'HBf<', 0, DeviceObject, 0);
|
|
|
|
return ntStatus;
|
|
}
|
|
|
|
|
|
ULONG
|
|
DBCLASS_IsHubPartOf_DBC(
|
|
PDEVICE_OBJECT DeviceObject
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This call reads a registry key that tells us if this usb hub is part
|
|
of a device bay controller
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - Device bay Filter FDO
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS
|
|
|
|
--*/
|
|
{
|
|
ULONG flags = 0;
|
|
NTSTATUS ntStatus;
|
|
PDEVICE_EXTENSION deviceExtension;
|
|
|
|
PAGED_CODE();
|
|
|
|
deviceExtension = DeviceObject->DeviceExtension;
|
|
|
|
ntStatus = DBCLASS_GetRegistryKeyValueForPdo(
|
|
deviceExtension->PhysicalDeviceObject,
|
|
FALSE,
|
|
IS_DEVICE_BAY_KEY,
|
|
sizeof(IS_DEVICE_BAY_KEY),
|
|
&flags,
|
|
sizeof(flags));
|
|
|
|
DBCLASS_KdPrint((2, "'GetRegistryKeyValueForPdo ntStatus = %x flags = %x\n",
|
|
ntStatus, flags));
|
|
|
|
return flags;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
DBCLASS_IsHubPartOfACPI_DBC(
|
|
PDEVICE_OBJECT DeviceObject
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is a call to a usb hub PDO
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - Device bay Filter FDO
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS
|
|
|
|
--*/
|
|
{
|
|
BOOLEAN isDB;
|
|
ULONG flags;
|
|
|
|
// see if it is an acpiDBC, if so mark it in
|
|
// the registry
|
|
if (DBCLASS_AcpiDBCHubParentPort != -1) {
|
|
PDEVICE_EXTENSION deviceExtension;
|
|
|
|
deviceExtension = DeviceObject->DeviceExtension;
|
|
|
|
DBCLASS_CheckForAcpiDeviceBayHubs(
|
|
deviceExtension->PhysicalDeviceObject,
|
|
(ULONG) DBCLASS_AcpiDBCHubParentPort);
|
|
}
|
|
|
|
flags = DBCLASS_IsHubPartOf_DBC(DeviceObject);
|
|
|
|
isDB = (BOOLEAN) flags & DBCLASS_HUB_IS_ACPI_DBC;
|
|
|
|
#ifdef DBG
|
|
if (isDB) {
|
|
DBCLASS_KdPrint((1, "'*** USBHUB for ACPI DBC Found\n"));
|
|
BRK_ON_TRAP();
|
|
}
|
|
#endif
|
|
|
|
return isDB;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
DBCLASS_IsHubPartOfUSB_DBC(
|
|
PDEVICE_OBJECT DeviceObject
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is a call to a usb hub PDO
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - Device bay Filter FDO
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS
|
|
|
|
--*/
|
|
{
|
|
BOOLEAN isDB;
|
|
ULONG flags;
|
|
|
|
flags = DBCLASS_IsHubPartOf_DBC(DeviceObject);
|
|
|
|
isDB = (BOOLEAN) flags & DBCLASS_HUB_IS_USB_DBC;
|
|
|
|
#ifdef DBG
|
|
if (isDB) {
|
|
DBCLASS_KdPrint((1, "'USBHUB for USB DBC Found!\n"));
|
|
BRK_ON_TRAP();
|
|
}
|
|
#endif
|
|
|
|
return isDB;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
DBCLASS_GetHubDBCGuid(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PUCHAR DbcGuid
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is a call to the root hub PDO
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - Device bay Filter FDO
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS ntStatus;
|
|
PDEVICE_EXTENSION deviceExtension;
|
|
|
|
PAGED_CODE();
|
|
deviceExtension = DeviceObject->DeviceExtension;
|
|
|
|
ntStatus = DBCLASS_GetRegistryKeyValueForPdo(
|
|
deviceExtension->PhysicalDeviceObject,
|
|
FALSE,
|
|
DBC_GUID_KEY,
|
|
sizeof(DBC_GUID_KEY),
|
|
DbcGuid,
|
|
8);
|
|
|
|
DBCLASS_KdPrint((2, "'GetRegistryKeyValueForPdo ntStatus = %x \n",
|
|
ntStatus));
|
|
|
|
#if DBG
|
|
DBCLASS_KdPrint((1, "'DBC GUID FOR HUB\n"));
|
|
DBCLASS_KdPrintGuid(1, DbcGuid);
|
|
#endif
|
|
|
|
return ntStatus;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
DBCLASS_SyncGetUsbInfo(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PDEVICE_OBJECT *ParentDeviceObject,
|
|
IN PDEVICE_OBJECT *RootHubPdo,
|
|
IN PULONG PortNumber
|
|
)
|
|
/* ++
|
|
*
|
|
* Routine Description:
|
|
*
|
|
* Arguments:
|
|
*
|
|
* Return Value:
|
|
*
|
|
* NTSTATUS
|
|
*
|
|
* -- */
|
|
{
|
|
NTSTATUS ntStatus, status;
|
|
PIRP irp;
|
|
KEVENT event;
|
|
IO_STATUS_BLOCK ioStatus;
|
|
PIO_STACK_LOCATION nextStack;
|
|
|
|
PAGED_CODE();
|
|
|
|
//
|
|
// issue a synchronous request to the Hub Pdo
|
|
//
|
|
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
|
|
|
irp = IoBuildDeviceIoControlRequest( IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO,
|
|
DeviceObject,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
0,
|
|
TRUE, // INTERNAL
|
|
&event,
|
|
&ioStatus);
|
|
|
|
if (NULL == irp) {
|
|
TRAP();
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
nextStack = IoGetNextIrpStackLocation(irp);
|
|
nextStack->Parameters.Others.Argument1 = ParentDeviceObject;
|
|
nextStack->Parameters.Others.Argument2 = PortNumber;
|
|
nextStack->Parameters.Others.Argument4 = RootHubPdo;
|
|
|
|
ntStatus = IoCallDriver(DeviceObject, irp);
|
|
|
|
if (ntStatus == STATUS_PENDING) {
|
|
|
|
status = KeWaitForSingleObject(&event,
|
|
Suspended,
|
|
KernelMode,
|
|
FALSE,
|
|
NULL);
|
|
|
|
} else {
|
|
ioStatus.Status = ntStatus;
|
|
}
|
|
|
|
ntStatus = ioStatus.Status;
|
|
|
|
DBCLASS_KdPrint((0, "'>>USB-PDO-INFO((%08X)) Parent = (%08X) Port = %d status = %x\n",
|
|
DeviceObject, *ParentDeviceObject, *PortNumber, ntStatus));
|
|
|
|
return ntStatus;
|
|
}
|
|
|
|
|
|
USHORT
|
|
DBCLASS_GetBayForUSBPdo(
|
|
PDBC_CONTEXT DbcContext,
|
|
PDEVICE_OBJECT PdoUSB
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
given a USB PDO figure out wich bay it is associated with
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
zero if not a device bay PDO.
|
|
|
|
--*/
|
|
{
|
|
USHORT bay = 0;
|
|
NTSTATUS ntStatus;
|
|
PDEVICE_OBJECT parent = NULL, rootHubPdo = NULL;
|
|
ULONG portNumber = 0xFFFFFFFF;
|
|
|
|
PAGED_CODE();
|
|
|
|
// find out what port this PDO is in
|
|
ntStatus = DBCLASS_SyncGetUsbInfo(PdoUSB,
|
|
&parent,
|
|
&rootHubPdo,
|
|
&portNumber);
|
|
|
|
if (NT_SUCCESS(ntStatus)) {
|
|
|
|
for (bay=1; bay <=NUMBER_OF_BAYS(DbcContext); bay++) {
|
|
DBCLASS_KdPrint((2, "'bay[%d]-> port %d, hub (%08X)\n",
|
|
bay,
|
|
DbcContext->BayInformation[bay].UsbHubPort,
|
|
DbcContext->BayInformation[bay].UsbHubPdo));
|
|
|
|
if (DbcContext->BayInformation[bay].UsbHubPort == portNumber
|
|
/*&&
|
|
DbcContext->BayInformation[bay].UsbHubPdo == parent */) {
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (!bay || bay > NUMBER_OF_BAYS(DbcContext)) {
|
|
bay = 0;
|
|
|
|
DBCLASS_KdPrint((2, "'No bay->port mapping for USB PDO\n"));
|
|
}
|
|
|
|
|
|
return bay;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
DBCLASS_SetupUSB_DBC(
|
|
PDBC_CONTEXT DbcContext
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
given a USB DbcContext, write the appropriate keys
|
|
to the registry
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS ntStatus = STATUS_SUCCESS;
|
|
ULONG flags = DBCLASS_HUB_IS_USB_DBC;
|
|
PDEVICE_OBJECT parentHubPdo = NULL, rootHubPdo = NULL;
|
|
ULONG portNumber;
|
|
|
|
|
|
|
|
// get the parent hub info
|
|
|
|
ntStatus = DBCLASS_SyncGetUsbInfo(
|
|
DbcContext->ControllerPdo,
|
|
&parentHubPdo,
|
|
&rootHubPdo,
|
|
&portNumber);
|
|
|
|
|
|
// set the keys
|
|
|
|
if (NT_SUCCESS(ntStatus)) {
|
|
ntStatus = DBCLASS_SetRegistryKeyValueForPdo(
|
|
parentHubPdo,
|
|
FALSE,
|
|
REG_DWORD,
|
|
IS_DEVICE_BAY_KEY,
|
|
sizeof(IS_DEVICE_BAY_KEY),
|
|
&flags,
|
|
sizeof(flags));
|
|
}
|
|
|
|
if (NT_SUCCESS(ntStatus)) {
|
|
ntStatus = DBCLASS_SetRegistryKeyValueForPdo(
|
|
parentHubPdo,
|
|
FALSE,
|
|
REG_BINARY,
|
|
DBC_GUID_KEY,
|
|
sizeof(DBC_GUID_KEY),
|
|
&DbcContext->SubsystemDescriptor.guid1394Link[0],
|
|
8);
|
|
}
|
|
|
|
return ntStatus;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
DBCLASS_CheckForAcpiDeviceBayHubs(
|
|
PDEVICE_OBJECT HubPdo,
|
|
ULONG AcpiDBCHubParentPort
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Check to see if this device object
|
|
is for a hub that is part of an ACPI DBC
|
|
|
|
Arguments:
|
|
|
|
AcpiDBCHubParentPort
|
|
0 = acpi hub is root otherwise upstream port on root
|
|
hub the ACPI hub is connected to
|
|
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS
|
|
|
|
--*/
|
|
{
|
|
PDEVICE_OBJECT parentHubPdo = NULL, rootHubPdo = NULL;
|
|
ULONG portNumber = 0;
|
|
BOOLEAN writeKeys = FALSE;
|
|
NTSTATUS ntStatus;
|
|
|
|
// get the root hub PDO
|
|
ntStatus = DBCLASS_SyncGetUsbInfo(
|
|
HubPdo,
|
|
&parentHubPdo,
|
|
&rootHubPdo,
|
|
&portNumber);
|
|
|
|
// failure indicates this is root
|
|
if (!NT_SUCCESS(ntStatus)) {
|
|
ntStatus = STATUS_SUCCESS;
|
|
rootHubPdo = HubPdo;
|
|
}
|
|
|
|
if (NT_SUCCESS(ntStatus)) {
|
|
|
|
DBCLASS_KdPrint((1, "'>**Check Hub: RHPDO = %x, parentPDO %x, port %d\n",
|
|
rootHubPdo,
|
|
parentHubPdo,
|
|
portNumber));
|
|
|
|
// is this the root hub?
|
|
if (HubPdo == rootHubPdo) {
|
|
// Yes
|
|
if (AcpiDBCHubParentPort == 0) {
|
|
// root hub is acpi hub
|
|
writeKeys = TRUE;
|
|
}
|
|
|
|
} else {
|
|
// is the parent the root hub?
|
|
if (parentHubPdo == rootHubPdo) {
|
|
// Yes
|
|
if (AcpiDBCHubParentPort == portNumber) {
|
|
// root hub ius acpi hub
|
|
writeKeys = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (writeKeys) {
|
|
ULONG flags;
|
|
|
|
flags = DBCLASS_HUB_IS_ACPI_DBC;
|
|
|
|
DBCLASS_SetRegistryKeyValueForPdo(
|
|
HubPdo,
|
|
FALSE,
|
|
REG_DWORD,
|
|
IS_DEVICE_BAY_KEY,
|
|
sizeof(IS_DEVICE_BAY_KEY),
|
|
&flags,
|
|
sizeof(flags));
|
|
|
|
|
|
// DBCLASS_SetRegistryKeyValueForPdo(
|
|
// HubPdo,
|
|
// FALSE,
|
|
// REG_BINARY,
|
|
// DBC_GUID_KEY,
|
|
// sizeof(DBC_GUID_KEY),
|
|
// &DbcContext->SubsystemDescriptor.guid1394Link[0],
|
|
// 8);
|
|
}
|
|
|
|
return ntStatus;
|
|
}
|