Beispiel #1
0
/**
 * Remove a PDO node from a bus.  Internal.
 *
 * @v bus             The bus to remove the node from.
 * @v node            The PDO node to remove from its parent bus.
 *
 * Don't call this function yourself.  It doesn't perform any error-checking.
 */
static VOID STDCALL WvlBusRemoveNode_(
    WVL_SP_BUS_T bus,
    WVL_SP_BUS_NODE node
  ) {
    KIRQL irql;

    DBG(
        "Removing PDO 0x%08X from bus 0x%08X.\n",
        (PVOID) node->BusPrivate_.Pdo,
        (PVOID) bus
      );
    KeAcquireSpinLock(&bus->BusPrivate_.NodeLock, &irql);
    RemoveEntryList(&node->BusPrivate_.Link);
    bus->BusPrivate_.NodeCount--;
    KeReleaseSpinLock(&bus->BusPrivate_.NodeLock, irql);
    node->Linked = FALSE;
    ObDereferenceObject(node->BusPrivate_.Pdo);
    /* We might be floating. */
    if (bus->Pdo)
      IoInvalidateDeviceRelations(bus->Pdo, BusRelations);
    /* Hack: Use the new method for the main bus */
    if (bus == &WvBus)
      WvlRemoveDeviceFromMainBus(node->BusPrivate_.Pdo);
    return;
  }
Beispiel #2
0
/**
 * Add a PDO node to a bus' list of children.  Internal.
 *
 * @v bus               The bus to add the node to.
 * @v new_node          The PDO node to add to the bus.
 *
 * Don't call this function yourself.  It doesn't perform any error-checking.
 */
static VOID STDCALL WvlBusAddNode_(WVL_SP_BUS_T bus, WVL_SP_BUS_NODE new_node) {
    PLIST_ENTRY walker;
    KIRQL irql;

    DBG(
        "Adding PDO %p to bus %p.\n",
        (PVOID) new_node->BusPrivate_.Pdo,
        (PVOID) bus
      );
    ObReferenceObject(new_node->BusPrivate_.Pdo);
    /* It's too bad about having both linked list and bus ref. */
    new_node->BusPrivate_.Bus = bus;

    /* Find a slot for the new child. */
    walker = &bus->BusPrivate_.Nodes;
    new_node->BusPrivate_.Num = 0;
    KeAcquireSpinLock(&bus->BusPrivate_.NodeLock, &irql);
    while ((walker = walker->Flink) != &bus->BusPrivate_.Nodes) {
        WVL_SP_BUS_NODE node = CONTAINING_RECORD(
            walker,
            WVL_S_BUS_NODE,
            BusPrivate_.Link
          );

        if (
            node->BusPrivate_.Num &&
            (node->BusPrivate_.Link.Blink == &bus->BusPrivate_.Nodes)
          ) {
            /* The first node's unit number is != 0.  Insert here. */
            break;
          }
        if (node->BusPrivate_.Num > new_node->BusPrivate_.Num) {
            /* There is a gap so insert here. */
            break;
          }
        /* Continue trying to find a slot. */
        new_node->BusPrivate_.Num++;
      } /* while */
    /* Insert before walker. */
    InsertTailList(walker, &new_node->BusPrivate_.Link);
    bus->BusPrivate_.NodeCount++;
    KeReleaseSpinLock(&bus->BusPrivate_.NodeLock, irql);
    new_node->Linked = TRUE;
    /* We might be floating. */
    if (bus->Pdo)
      IoInvalidateDeviceRelations(bus->Pdo, BusRelations);
    /* Hack: Use the new method for the main bus */
    if (bus == &WvBus)
      WvlAddDeviceToMainBus(new_node->BusPrivate_.Pdo);
    return;
  }
Beispiel #3
0
NTSTATUS StartIrpClose(
    IN PC0C_IO_PORT pIoPort,
    IN PLIST_ENTRY pQueueToComplete)
{
  UNREFERENCED_PARAMETER(pQueueToComplete);

  if (!pIoPort->exclusiveMode) {
    PIRP pIrp;

    InterlockedDecrement(&pIoPort->pDevExt->openCount);
    pIrp = pIoPort->irpQueues[C0C_QUEUE_CLOSE].pCurrent;
    pIrp->IoStatus.Information = 0;
    return STATUS_SUCCESS;
  }

  IoInvalidateDeviceRelations(pIoPort->pPhDevObj, BusRelations);
  SetCloseTimeout(pIoPort);

  return STATUS_PENDING;
}
Beispiel #4
0
NTSTATUS FdoPortClose(IN PC0C_FDOPORT_EXTENSION pDevExt, IN PIRP pIrp)
{
  NTSTATUS status;
  LIST_ENTRY queueToComplete;
  KIRQL oldIrql;
  PC0C_IO_PORT pIoPort;

  pIoPort = pDevExt->pIoPortLocal;

  pIoPort->isOpen = FALSE;

  if (pIoPort->pIoPortRemote->plugInMode)
    IoInvalidateDeviceRelations(pIoPort->pIoPortRemote->pPhDevObj, BusRelations);

  InitializeListHead(&queueToComplete);

  KeAcquireSpinLock(pIoPort->pIoLock, &oldIrql);

  pIoPort->escapeChar = 0;
  pIoPort->writeHoldingRemote = 0;
  pIoPort->sendXonXoff = 0;
  SetModemControl(pIoPort, C0C_MCR_OUT2, C0C_MCR_MASK | C0C_MCR_OPEN, &queueToComplete);
  FreeBuffer(&pIoPort->readBuf);
  SetBreakHolding(pIoPort, FALSE, &queueToComplete);

  KeReleaseSpinLock(pIoPort->pIoLock, oldIrql);

  FdoPortCompleteQueue(&queueToComplete);

  status = FdoPortStartIrp(pIoPort, pIrp, C0C_QUEUE_CLOSE, StartIrpClose);

  if (status != STATUS_PENDING) {
    pIrp->IoStatus.Status = status;
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  }

  return status;
}
Beispiel #5
0
NTSTATUS
bus_unplug_dev (
    int addr,
    PFDO_DEVICE_DATA            fdodata
    )
{
    PLIST_ENTRY         entry;
    PPDO_DEVICE_DATA    pdodata;
    int found=0, all;

    PAGED_CODE ();

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

    all = (0 == addr);

    ExAcquireFastMutex (&fdodata->Mutex);

    if (all) {
        Bus_KdPrint (fdodata, BUS_DBG_IOCTL_NOISE,
                      ("Plugging out all the devices!\n"));
    } else {
        Bus_KdPrint (fdodata, BUS_DBG_IOCTL_NOISE,
                      ("Plugging out %d\n", addr));
    }

    if (fdodata->NumPDOs == 0) {
        //
        // We got a 2nd plugout...somebody in user space isn't playing nice!!!
        //
        Bus_KdPrint (fdodata, BUS_DBG_IOCTL_ERROR,
                      ("BAD BAD BAD...2 removes!!! Send only one!\n"));
        ExReleaseFastMutex (&fdodata->Mutex);
        return STATUS_NO_SUCH_DEVICE;
    }

    for (entry = fdodata->ListOfPDOs.Flink;
         entry != &fdodata->ListOfPDOs;
         entry = entry->Flink) {

        pdodata = CONTAINING_RECORD (entry, PDO_DEVICE_DATA, Link);

        Bus_KdPrint (fdodata, BUS_DBG_IOCTL_NOISE,
                      ("found device %d\n", pdodata->SerialNo));

        if (all || addr == pdodata->SerialNo) {
            Bus_KdPrint (fdodata, BUS_DBG_IOCTL_INFO,
                          ("Plugged out %d\n", pdodata->SerialNo));
            pdodata->Present = FALSE;
	    complete_pending_read_irp(pdodata);
            found = 1;
            if (!all) {
                break;
            }
        }
    }

    ExReleaseFastMutex (&fdodata->Mutex);

    if (found) {
        IoInvalidateDeviceRelations (fdodata->UnderlyingPDO, BusRelations);

    ExAcquireFastMutex (&fdodata->Mutex);

    for (entry = fdodata->ListOfPDOs.Flink;
         entry != &fdodata->ListOfPDOs;
         entry = entry->Flink) {

        pdodata = CONTAINING_RECORD (entry, PDO_DEVICE_DATA, Link);

        if( pdodata->Present ==FALSE){
            complete_pending_irp(pdodata);
	}
    }
    ExReleaseFastMutex (&fdodata->Mutex);
    Bus_KdPrint (fdodata, BUS_DBG_IOCTL_ERROR,
                  ("Device %d is not present\n", addr));
    return  STATUS_SUCCESS;
    }


    return STATUS_INVALID_PARAMETER;
}
Beispiel #6
0
NTSTATUS bus_plugin_dev(ioctl_usbvbus_plugin * plugin, PFDO_DEVICE_DATA  fdodata,
		PFILE_OBJECT fo)
{
    PDEVICE_OBJECT      pdo;
    PPDO_DEVICE_DATA    pdodata, old_pdodata;
    NTSTATUS            status;
    ULONG               len;
    PLIST_ENTRY         entry;
    unsigned long i;

    PAGED_CODE ();

    Bus_KdPrint (fdodata, BUS_DBG_PNP_INFO,
                  ("Exposing PDO\n"
                   "======addr:  %d\n"
                   "======vendor:product: %04x:%04x\n",
                   plugin->addr,
		   plugin->vendor, plugin->product));

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

    ExAcquireFastMutex (&fdodata->Mutex);

    for (entry = fdodata->ListOfPDOs.Flink;
         entry != &fdodata->ListOfPDOs;
         entry = entry->Flink) {

        pdodata = CONTAINING_RECORD (entry, PDO_DEVICE_DATA, Link);
        if (plugin->addr == pdodata->SerialNo &&
            pdodata->DevicePnPState != SurpriseRemovePending)
        {
	    ExReleaseFastMutex (&fdodata->Mutex);
	    return STATUS_INVALID_PARAMETER;
        }
    }

    ExReleaseFastMutex (&fdodata->Mutex);

    // Create the PDO
    //


    Bus_KdPrint(fdodata, BUS_DBG_PNP_NOISE,
                 ("fdodata->NextLowerDriver = 0x%p\n", fdodata->NextLowerDriver));

    //
    // PDO must have a name. You should let the system auto generate a
    // name by specifying FILE_AUTOGENERATED_DEVICE_NAME in the
    // DeviceCharacteristics parameter. Let us create a secure deviceobject,
    // in case the child gets installed as a raw device (RawDeviceOK), to prevent
    // an unpriviledged user accessing our device. This function is avaliable
    // in a static WDMSEC.LIB and can be used in Win2k, XP, and Server 2003
    // Just make sure that  the GUID specified here is not a setup class GUID.
    // If you specify a setup class guid, you must make sure that class is
    // installed before enumerating the PDO.
    //

    status = IoCreateDeviceSecure(fdodata->Self->DriverObject,
                sizeof (PDO_DEVICE_DATA),
                NULL,
                FILE_DEVICE_BUS_EXTENDER,
                FILE_AUTOGENERATED_DEVICE_NAME |FILE_DEVICE_SECURE_OPEN,
                FALSE,
                &SDDL_DEVOBJ_SYS_ALL_ADM_ALL, // read wdmsec.h for more info
                (LPCGUID)&GUID_SD_BUSENUM_PDO,
                &pdo);
    if (!NT_SUCCESS (status)) {
        return status;
    }

    pdodata = (PPDO_DEVICE_DATA) pdo->DeviceExtension;

#define HARDWARE_IDS_TPL L"USB\\Vid_%04x&Pid_%04x&Rev_%04xZUSB\\Vid_%04x&Pid_%04xZ"

    len = sizeof(HARDWARE_IDS_TPL);
    pdodata->HardwareIDs =
            ExAllocatePoolWithTag (NonPagedPool, len, BUSENUM_POOL_TAG);
    if (NULL == pdodata->HardwareIDs) {
        IoDeleteDevice(pdo);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    RtlStringCchPrintfW(pdodata->HardwareIDs, len/sizeof(wchar_t),
		HARDWARE_IDS_TPL,
	        plugin->vendor, plugin->product, plugin->version,
	        plugin->vendor, plugin->product);
    for(i=0;i<sizeof(HARDWARE_IDS_TPL);i++){
	    if('Z'==pdodata->HardwareIDs[i])
		    pdodata->HardwareIDs[i]=0;
    }
#define COMPATIBLE_IDS_TPL L"USB\\Class_%02x&SubClass_%02x&Prot_%02xZUSB\\Class_%02x&SubClass_%02xZUSB\\Class_%02xZ"
#define COMPATIBLE_COMPOSITE_IDS_TPL L"USB\\Class_%02x&SubClass_%02x&Prot_%02xZUSB\\Class_%02x&SubClass_%02xZUSB\\Class_%02xZUSB\\COMPOSITEZ"
    if(plugin->inum>1)
	   len = sizeof(COMPATIBLE_COMPOSITE_IDS_TPL);
    else
	   len = sizeof(COMPATIBLE_IDS_TPL);
    pdodata->compatible_ids =
            ExAllocatePoolWithTag (NonPagedPool, len, BUSENUM_POOL_TAG);
    RtlZeroMemory(pdodata->compatible_ids, len);
    if (NULL == pdodata->compatible_ids) {
	ExFreePool(pdodata->HardwareIDs);
        IoDeleteDevice(pdo);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    pdodata->compatible_ids_len = len;
    RtlStringCchPrintfW(pdodata->compatible_ids, len/sizeof(wchar_t),
		(plugin->inum>1)?COMPATIBLE_COMPOSITE_IDS_TPL:COMPATIBLE_IDS_TPL,
	        plugin->int0_class, plugin->int0_subclass, plugin->int0_protocol,
		plugin->int0_class, plugin->int0_subclass,
		plugin->int0_class);
    for(i=0;i<len;i++){
	    if('Z'==pdodata->compatible_ids[i])
		    pdodata->compatible_ids[i]=0;
    }
    old_pdodata = (PPDO_DEVICE_DATA) InterlockedCompareExchange(&((LONG)fo->FsContext), (LONG) pdodata, 0);
    if(old_pdodata){
	    KdPrint(("you can't plugin again"));
	    ExFreePool(pdodata->HardwareIDs);
	    ExFreePool(pdodata->compatible_ids);
	   IoDeleteDevice(pdo);
           return STATUS_INVALID_PARAMETER;
    }
    pdodata->SerialNo = plugin->addr;
    pdodata->fo = fo;
    pdodata->devid = plugin->devid;
    pdodata->speed = plugin->speed;
    bus_init_pdo (pdo, fdodata);

    //
    // Device Relation changes if a new pdo is created. So let
    // the PNP system now about that. This forces it to send bunch of pnp
    // queries and cause the function driver to be loaded.
    //

    IoInvalidateDeviceRelations (fdodata->UnderlyingPDO, BusRelations);

    return status;
}
NTSTATUS
Serenum_InternIoCtl (
    PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
/*++
Routine Description:

--*/
{
    PIO_STACK_LOCATION      irpStack;
    NTSTATUS                status;
    PCOMMON_DEVICE_DATA     commonData;
    PPDO_DEVICE_DATA        pdoData;

//    PAGED_CODE();


    commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;
    status=IoAcquireRemoveLock(&commonData->RemoveLock,Irp);
    if(!NT_SUCCESS(status)){
        Irp->IoStatus.Information=0;
        Irp->IoStatus.Status=status;
        IoCompleteRequest(Irp,IO_NO_INCREMENT);
        return status;
    }
    status = STATUS_SUCCESS;
    irpStack = IoGetCurrentIrpStackLocation (Irp);
    ASSERT (IRP_MJ_INTERNAL_DEVICE_CONTROL == irpStack->MajorFunction);

    
    pdoData = (PPDO_DEVICE_DATA) DeviceObject->DeviceExtension;

    //
    // We only take Internal Device Control requests for the PDO.
    // That is the objects on the bus (representing the serial ports)
    //
    // We do pass on the irp if this comes into the fdo, but not if it comes
    // into the pdo.
    //

    if (commonData->IsFDO) {
        return Serenum_DispatchPassThroughWithoutAcquire(
            DeviceObject,
            Irp);
    }else{
        //buffer = Irp->UserBuffer;

        switch (irpStack->Parameters.DeviceIoControl.IoControlCode) {
        case IOCTL_INTERNAL_SERENUM_REMOVE_SELF:
            Serenum_KdPrint(pdoData, SER_DBG_SS_TRACE, ("Remove self\n"));

            ((PFDO_DEVICE_DATA) pdoData->ParentFdo->DeviceExtension)->
                PDOForcedRemove = TRUE;
            Serenum_PDO_EnumMarkMissing(pdoData->ParentFdo->DeviceExtension, DeviceObject->DeviceExtension);

            IoInvalidateDeviceRelations(
                ((PFDO_DEVICE_DATA) pdoData->ParentFdo->DeviceExtension)->
                UnderlyingPDO,
                BusRelations );
            status = STATUS_SUCCESS;
            Irp->IoStatus.Information = 0;
            break;

        default:
            //
            // Pass it through
            //
            return Serenum_DispatchPassThroughWithoutAcquire(DeviceObject, Irp);
        }
    }

    Irp->IoStatus.Status = status;
    IoCompleteRequest (Irp, IO_NO_INCREMENT);
    IoReleaseRemoveLock(&commonData->RemoveLock,Irp);
    return status;
}
Beispiel #8
0
void add_volume_device(superblock* sb, PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath, UINT64 length, ULONG disk_num, ULONG part_num) {
    NTSTATUS Status;
    LIST_ENTRY* le;
    PDEVICE_OBJECT DeviceObject;
    volume_child* vc;
    PFILE_OBJECT FileObject;
    UNICODE_STRING devpath2;
    BOOL inserted = FALSE, new_pdo = FALSE;
    pdo_device_extension* pdode = NULL;
    PDEVICE_OBJECT pdo = NULL;

    if (devpath->Length == 0)
        return;

    ExAcquireResourceExclusiveLite(&pdo_list_lock, TRUE);

    le = pdo_list.Flink;
    while (le != &pdo_list) {
        pdo_device_extension* pdode2 = CONTAINING_RECORD(le, pdo_device_extension, list_entry);

        if (RtlCompareMemory(&pdode2->uuid, &sb->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
            pdode = pdode2;
            break;
        }

        le = le->Flink;
    }

    Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject);
    if (!NT_SUCCESS(Status)) {
        ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
        ExReleaseResourceLite(&pdo_list_lock);
        return;
    }

    if (!pdode) {
        if (no_pnp) {
            Status = IoReportDetectedDevice(drvobj, InterfaceTypeUndefined, 0xFFFFFFFF, 0xFFFFFFFF, NULL, NULL, 0, &pdo);

            if (!NT_SUCCESS(Status)) {
                ERR("IoReportDetectedDevice returned %08x\n", Status);
                ExReleaseResourceLite(&pdo_list_lock);
                return;
            }

            pdode = ExAllocatePoolWithTag(NonPagedPool, sizeof(pdo_device_extension), ALLOC_TAG);

            if (!pdode) {
                ERR("out of memory\n");
                ExReleaseResourceLite(&pdo_list_lock);
                return;
            }
        } else {
            Status = IoCreateDevice(drvobj, sizeof(pdo_device_extension), NULL, FILE_DEVICE_DISK,
                                    FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &pdo);
            if (!NT_SUCCESS(Status)) {
                ERR("IoCreateDevice returned %08x\n", Status);
                ExReleaseResourceLite(&pdo_list_lock);
                goto fail;
            }

            pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;

            pdode = pdo->DeviceExtension;
        }

        RtlZeroMemory(pdode, sizeof(pdo_device_extension));

        pdode->type = VCB_TYPE_PDO;
        pdode->pdo = pdo;
        pdode->uuid = sb->uuid;

        ExInitializeResourceLite(&pdode->child_lock);
        InitializeListHead(&pdode->children);
        pdode->num_children = sb->num_devices;
        pdode->children_loaded = 0;

        pdo->Flags &= ~DO_DEVICE_INITIALIZING;
        pdo->SectorSize = (USHORT)sb->sector_size;

        ExAcquireResourceExclusiveLite(&pdode->child_lock, TRUE);

        new_pdo = TRUE;
    } else {
        ExAcquireResourceExclusiveLite(&pdode->child_lock, TRUE);
        ExConvertExclusiveToSharedLite(&pdo_list_lock);

        le = pdode->children.Flink;
        while (le != &pdode->children) {
            volume_child* vc2 = CONTAINING_RECORD(le, volume_child, list_entry);

            if (RtlCompareMemory(&vc2->uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
                // duplicate, ignore
                ExReleaseResourceLite(&pdode->child_lock);
                ExReleaseResourceLite(&pdo_list_lock);
                goto fail;
            }

            le = le->Flink;
        }
    }

    vc = ExAllocatePoolWithTag(PagedPool, sizeof(volume_child), ALLOC_TAG);
    if (!vc) {
        ERR("out of memory\n");

        ExReleaseResourceLite(&pdode->child_lock);
        ExReleaseResourceLite(&pdo_list_lock);

        goto fail;
    }

    vc->uuid = sb->dev_item.device_uuid;
    vc->devid = sb->dev_item.dev_id;
    vc->generation = sb->generation;
    vc->notification_entry = NULL;

    Status = IoRegisterPlugPlayNotification(EventCategoryTargetDeviceChange, 0, FileObject,
                                            drvobj, pnp_removal, pdode, &vc->notification_entry);
    if (!NT_SUCCESS(Status))
        WARN("IoRegisterPlugPlayNotification returned %08x\n", Status);

    vc->devobj = DeviceObject;
    vc->fileobj = FileObject;

    devpath2 = *devpath;

    // The PNP path sometimes begins \\?\ and sometimes \??\. We need to remove this prefix
    // so we can compare properly if the device is removed.
    if (devpath->Length > 4 * sizeof(WCHAR) && devpath->Buffer[0] == '\\' && (devpath->Buffer[1] == '\\' || devpath->Buffer[1] == '?') &&
        devpath->Buffer[2] == '?' && devpath->Buffer[3] == '\\') {
        devpath2.Buffer = &devpath2.Buffer[3];
        devpath2.Length -= 3 * sizeof(WCHAR);
        devpath2.MaximumLength -= 3 * sizeof(WCHAR);
    }

    vc->pnp_name.Length = vc->pnp_name.MaximumLength = devpath2.Length;
    vc->pnp_name.Buffer = ExAllocatePoolWithTag(PagedPool, devpath2.Length, ALLOC_TAG);

    if (vc->pnp_name.Buffer)
        RtlCopyMemory(vc->pnp_name.Buffer, devpath2.Buffer, devpath2.Length);
    else {
        ERR("out of memory\n");
        vc->pnp_name.Length = vc->pnp_name.MaximumLength = 0;
    }

    vc->size = length;
    vc->seeding = sb->flags & BTRFS_SUPERBLOCK_FLAGS_SEEDING ? TRUE : FALSE;
    vc->disk_num = disk_num;
    vc->part_num = part_num;
    vc->had_drive_letter = FALSE;

    le = pdode->children.Flink;
    while (le != &pdode->children) {
        volume_child* vc2 = CONTAINING_RECORD(le, volume_child, list_entry);

        if (vc2->generation < vc->generation) {
            if (le == pdode->children.Flink)
                pdode->num_children = sb->num_devices;

            InsertHeadList(vc2->list_entry.Blink, &vc->list_entry);
            inserted = TRUE;
            break;
        }

        le = le->Flink;
    }

    if (!inserted)
        InsertTailList(&pdode->children, &vc->list_entry);

    pdode->children_loaded++;

    if (pdode->vde && pdode->vde->mounted_device) {
        device_extension* Vcb = pdode->vde->mounted_device->DeviceExtension;

        ExAcquireResourceExclusiveLite(&Vcb->tree_lock, TRUE);

        le = Vcb->devices.Flink;
        while (le != &Vcb->devices) {
            device* dev = CONTAINING_RECORD(le, device, list_entry);

            if (!dev->devobj && RtlCompareMemory(&dev->devitem.device_uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
                dev->devobj = DeviceObject;
                dev->disk_num = disk_num;
                dev->part_num = part_num;
                init_device(Vcb, dev, FALSE);
                break;
            }

            le = le->Flink;
        }

        ExReleaseResourceLite(&Vcb->tree_lock);
    }

    if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
        pdode->removable = TRUE;

        if (pdode->vde && pdode->vde->device)
            pdode->vde->device->Characteristics |= FILE_REMOVABLE_MEDIA;
    }

    if (pdode->num_children == pdode->children_loaded || (pdode->children_loaded == 1 && allow_degraded_mount(&sb->uuid))) {
        if (pdode->num_children == 1) {
            Status = remove_drive_letter(mountmgr, devpath);
            if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND)
                WARN("remove_drive_letter returned %08x\n", Status);

            vc->had_drive_letter = NT_SUCCESS(Status);
        } else {
            le = pdode->children.Flink;

            while (le != &pdode->children) {
                UNICODE_STRING name;

                vc = CONTAINING_RECORD(le, volume_child, list_entry);

                name.Length = name.MaximumLength = vc->pnp_name.Length + (3 * sizeof(WCHAR));
                name.Buffer = ExAllocatePoolWithTag(PagedPool, name.Length, ALLOC_TAG);

                if (!name.Buffer) {
                    ERR("out of memory\n");

                    ExReleaseResourceLite(&pdode->child_lock);
                    ExReleaseResourceLite(&pdo_list_lock);

                    goto fail;
                }

                RtlCopyMemory(name.Buffer, L"\\??", 3 * sizeof(WCHAR));
                RtlCopyMemory(&name.Buffer[3], vc->pnp_name.Buffer, vc->pnp_name.Length);

                Status = remove_drive_letter(mountmgr, &name);

                if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND)
                    WARN("remove_drive_letter returned %08x\n", Status);

                ExFreePool(name.Buffer);

                vc->had_drive_letter = NT_SUCCESS(Status);

                le = le->Flink;
            }
        }

        if ((!new_pdo || !no_pnp) && pdode->vde) {
            Status = IoSetDeviceInterfaceState(&pdode->vde->bus_name, TRUE);
            if (!NT_SUCCESS(Status))
                WARN("IoSetDeviceInterfaceState returned %08x\n", Status);
        }
    }

    ExReleaseResourceLite(&pdode->child_lock);

    if (new_pdo) {
        control_device_extension* cde = master_devobj->DeviceExtension;

        InsertTailList(&pdo_list, &pdode->list_entry);

        if (!no_pnp)
            IoInvalidateDeviceRelations(cde->buspdo, BusRelations);
    }

    ExReleaseResourceLite(&pdo_list_lock);

    if (new_pdo && no_pnp)
        AddDevice(drvobj, pdo);

    return;

fail:
    ObDereferenceObject(FileObject);
}
Beispiel #9
0
NTSTATUS FdoPortOpen(IN PC0C_FDOPORT_EXTENSION pDevExt)
{
  LIST_ENTRY queueToComplete;
  PUCHAR pBase;
  ULONG size;
  KIRQL oldIrql;
  PC0C_IO_PORT pIoPort;

  if (InterlockedIncrement(&pDevExt->openCount) != 1) {
    InterlockedDecrement(&pDevExt->openCount);
    return STATUS_ACCESS_DENIED;
  }

  pIoPort = pDevExt->pIoPortLocal;

  if (pIoPort->plugInMode && !pIoPort->pIoPortRemote->isOpen) {
    InterlockedDecrement(&pDevExt->openCount);
    return STATUS_ACCESS_DENIED;
  }

  if (pIoPort->exclusiveMode)
    IoInvalidateDeviceRelations(pIoPort->pPhDevObj, BusRelations);

  switch (MmQuerySystemSize()) {
  case MmLargeSystem:
    size = 4096;
    pBase = (PUCHAR)C0C_ALLOCATE_POOL(NonPagedPool, size);
    if (pBase)
      break;
  case MmMediumSystem:
    size = 1024;
    pBase = (PUCHAR)C0C_ALLOCATE_POOL(NonPagedPool, size);
    if (pBase)
      break;
  case MmSmallSystem:
    size = 128;
    pBase = (PUCHAR)C0C_ALLOCATE_POOL(NonPagedPool, size);
    if (pBase)
      break;
  default:
    size = 0;
    pBase = NULL;
  }

  InitializeListHead(&queueToComplete);

#if ENABLE_TRACING
  if (pIoPort->amountInWriteQueue) {
    NTSTATUS status;
    UNICODE_STRING msg;

    status = STATUS_SUCCESS;
    RtlInitUnicodeString(&msg, NULL);
    StrAppendStr0(&status, &msg, L"!!!WARNING!!! amountInWriteQueue = ");
    StrAppendNum(&status, &msg, pIoPort->amountInWriteQueue, 10);

    Trace0((PC0C_COMMON_EXTENSION)pDevExt, msg.Buffer);

    StrFree(&msg);
  }
#endif /* ENABLE_TRACING */

  KeAcquireSpinLock(pIoPort->pIoLock, &oldIrql);

  InitBuffer(&pIoPort->readBuf, pBase, size);

  pIoPort->amountInWriteQueue = 0;
  pIoPort->tryWrite = FALSE;
  pIoPort->errors = 0;
  pIoPort->waitMask = 0;
  pIoPort->eventMask = 0;
  RtlZeroMemory(&pIoPort->perfStats, sizeof(pIoPort->perfStats));
  pIoPort->handFlow.XoffLimit = size >> 3;
  pIoPort->handFlow.XonLimit = size >> 1;
  pIoPort->pIoPortRemote->brokeIdleChars = 0;

  SetHandFlow(pIoPort, NULL, &queueToComplete);
  SetModemControl(pIoPort, C0C_MCR_OPEN, C0C_MCR_OPEN, &queueToComplete);

  if (pIoPort->pIoPortRemote->pWriteDelay && pIoPort->pIoPortRemote->brokeCharsProbability > 0)
    StartWriteDelayTimer(pIoPort->pIoPortRemote->pWriteDelay);

  KeReleaseSpinLock(pIoPort->pIoLock, oldIrql);

  pIoPort->isOpen = TRUE;

  if (pIoPort->pIoPortRemote->plugInMode)
    IoInvalidateDeviceRelations(pIoPort->pIoPortRemote->pPhDevObj, BusRelations);

  FdoPortCompleteQueue(&queueToComplete);

  return STATUS_SUCCESS;
}
Beispiel #10
0
NTSTATUS
NdasPortFdoDeviceControlPlugInLogicalUnit(
	__in PNDASPORT_FDO_EXTENSION FdoExtension,
	__in PNDAS_LOGICALUNIT_DESCRIPTOR LogicalUnitDescriptor,
	__in ULONG InternalFlags)
{
	NTSTATUS status;
	PDEVICE_OBJECT physicalDeviceObject;

	PNDASPORT_PDO_EXTENSION pdoExtension;
	NDAS_LOGICALUNIT_INTERFACE logicalUnitInterface;
	ULONG logicalUnitExtensionSize;
	ULONG logicalUnitSrbExtensionSize;
	NDASPORT_PDO_EXTENSION tmp = {0};
	PNDAS_LU_QUERY_NDAS_LOGICALUNIT_INTERFACE logicalUnitInterfaceQuery;

	PFILE_OBJECT externalFileObject;
	PDEVICE_OBJECT externalDeviceObject;

	PLIST_ENTRY entry;

	PAGED_CODE();

	NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_INFORMATION,
		"PlugInLogicalUnit: Fdo=%p, Descriptor=%p (%d,%d,%d,%d)\n", 
		FdoExtension->DeviceObject, 
		LogicalUnitDescriptor,
		LogicalUnitDescriptor->Address.PortNumber,
		LogicalUnitDescriptor->Address.PathId,
		LogicalUnitDescriptor->Address.TargetId,
		LogicalUnitDescriptor->Address.Lun);

	if (LogicalUnitDescriptor->Address.PortNumber != FdoExtension->PortNumber)
	{
		NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_ERROR,
			"Port Number is not invalid. UserPortNumber=%d, PortNumber=%d\n",
			LogicalUnitDescriptor->Address.PortNumber,
			FdoExtension->PortNumber);

		return STATUS_INVALID_PARAMETER_1;
	}

	//
	// Following code walks the PDO list to check whether
	// the input serial number is unique.
	// Let's first assume it's unique
	//

	tmp.IsTemporary = TRUE;
	tmp.LogicalUnitAddress = LogicalUnitDescriptor->Address;

	//
	// Just be aware: If a user unplugs and plugs in the device 
	// immediately, in a split second, even before we had a chance to 
	// clean up the previous PDO completely, we might fail to 
	// accept the device.
	//

	ExAcquireFastMutex (&FdoExtension->Mutex);

	for (entry = FdoExtension->ListOfPDOs.Flink;
		entry != &FdoExtension->ListOfPDOs;
		entry = entry->Flink) 
	{
		PNDASPORT_PDO_EXTENSION pdoEntry;
		pdoEntry = CONTAINING_RECORD(entry, NDASPORT_PDO_EXTENSION, Link);

		if (tmp.LogicalUnitAddress.Address == pdoEntry->LogicalUnitAddress.Address)
		{
			ExReleaseFastMutex (&FdoExtension->Mutex); 
			return STATUS_OBJECT_NAME_COLLISION;
		}
	}

	//
	// We adds a temporary LU for the place holder
	//

	InsertTailList(&FdoExtension->ListOfPDOs, &tmp.Link);
	++(FdoExtension->NumberOfPDOs);

	ExReleaseFastMutex (&FdoExtension->Mutex); 

	//
	// Save the information to the registry
	//

	if (!TestFlag(InternalFlags, NDASPORT_FDO_PLUGIN_FLAG_NO_REGISTRY))
	{
		status = NdasPortFdoRegSaveLogicalUnit(
			FdoExtension, LogicalUnitDescriptor);

		if (!NT_SUCCESS(status))
		{
			NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_ERROR,
				"NdasPortFdoGetExtendedInterface failed, Status=%x\n", 
				status);

			//
			// Delete the temporary LU
			//
			ExAcquireFastMutex (&FdoExtension->Mutex);
			RemoveEntryList(&tmp.Link);
			--(FdoExtension->NumberOfPDOs);
			ExReleaseFastMutex (&FdoExtension->Mutex);

			return status;
		}
	}

	//
	// Create the PDO
	//

	status = STATUS_INVALID_PARAMETER;

	logicalUnitInterface.Version = NDAS_LOGICALUNIT_INTERFACE_VERSION;
	logicalUnitInterface.Size = sizeof(NDAS_LOGICALUNIT_INTERFACE);

	externalFileObject = NULL;
	externalDeviceObject = NULL;

	if (LogicalUnitDescriptor->Type & NdasExternalType)
	{
		status = NdasPortFdoGetExtendedInterface(
			&LogicalUnitDescriptor->ExternalTypeGuid,
			&externalFileObject,
			&externalDeviceObject,
			&logicalUnitInterfaceQuery);

		if (!NT_SUCCESS(status))
		{
			NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_ERROR,
				"NdasPortFdoGetExtendedInterface failed, Status=%x\n", 
				status);
		}
		else
		{
			status = (*logicalUnitInterfaceQuery)(
				LogicalUnitDescriptor,
				&logicalUnitInterface,
				&logicalUnitExtensionSize,
				&logicalUnitSrbExtensionSize);
		}

		//
		// Be sure to call ObDereferenceObject(externalFileObject)
		// on failure in this function or later when the PDO is destroyed
		// 
	}
	else
	{
		switch (LogicalUnitDescriptor->Type)
		{
		case NdasDiskDevice:
		case NdasAtaDevice:
			logicalUnitInterfaceQuery = NdasAtaDeviceGetNdasLogicalUnitInterface;
			break;
		default:
			logicalUnitInterfaceQuery = NULL;
			break;
		}

		if (NULL == logicalUnitInterfaceQuery)
		{
			status = STATUS_NOT_SUPPORTED;
		}
		else
		{
			status = (*logicalUnitInterfaceQuery)(
				LogicalUnitDescriptor,
				&logicalUnitInterface,
				&logicalUnitExtensionSize,
				&logicalUnitSrbExtensionSize);
		}
	}

	if (!NT_SUCCESS(status))
	{
		NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_ERROR,
			"GetNdasLogicalUnitInterface failed for %d, Status=%x\n", 
			LogicalUnitDescriptor->Type,
			status);

		//
		// Delete the temporary LU
		//
		ExAcquireFastMutex (&FdoExtension->Mutex);
		RemoveEntryList(&tmp.Link);
		--(FdoExtension->NumberOfPDOs);
		ExReleaseFastMutex (&FdoExtension->Mutex);

		//
		// Dereference External File Object if it is external
		//
		if (NULL != externalFileObject)
		{
			ObDereferenceObject(externalFileObject);
			externalFileObject = NULL;
			externalDeviceObject = NULL;
		}

		return status;
	}

	status = NdasPortPdoCreatePhysicalDeviceObject(
		FdoExtension,
		&logicalUnitInterface,
		LogicalUnitDescriptor,
		logicalUnitExtensionSize,
		logicalUnitSrbExtensionSize,
		externalDeviceObject,
		externalFileObject,
		&physicalDeviceObject);

	if (!NT_SUCCESS(status))
	{
		NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_ERROR,
			"NdasPortPdoCreatePhysicalDeviceObject failed, Status=%08X\n", status);

		//
		// Delete the temporary LU
		//
		ExAcquireFastMutex (&FdoExtension->Mutex);
		RemoveEntryList(&tmp.Link);
		--(FdoExtension->NumberOfPDOs);
		ExReleaseFastMutex (&FdoExtension->Mutex);

		//
		// Dereference External File Object if it is external
		//
		if (NULL != externalFileObject)
		{
			ObDereferenceObject(externalFileObject);
			externalFileObject = NULL;
			externalDeviceObject = NULL;
		}

		return status;
	}

	//
	// Remove the temporary entry and add the actual entry
	// We don't need to change the counter (-1 + +1 = 0 !)
	//

	pdoExtension = NdasPortPdoGetExtension(physicalDeviceObject);

	ExAcquireFastMutex(&FdoExtension->Mutex);

	RemoveEntryList(&tmp.Link);
	InsertTailList(&FdoExtension->ListOfPDOs, &pdoExtension->Link);

	ExReleaseFastMutex(&FdoExtension->Mutex);

	//
	// This should be the last step in initialization.
	//

	physicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

	NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_INFORMATION,
		"Child physical device object created, Pdo=%p\n", physicalDeviceObject);

	//
	// Device Relation changes if a new pdo is created. So let
	// the PNP system now about that. This forces it to send bunch of PNP
	// queries and cause the function driver to be loaded.
	//

	NdasPortFdoNotifyPnpEvent(
		FdoExtension,
		NdasPortLogicalUnitIsReady,
		LogicalUnitDescriptor->Address);

	NdasPortPdoNotifyWmiEvent(
		FdoExtension,
		NdasPortLogicalUnitIsReady,
		LogicalUnitDescriptor->Address);

	IoInvalidateDeviceRelations(FdoExtension->LowerPdo, BusRelations);

	return STATUS_SUCCESS;
}
Beispiel #11
0
NTSTATUS
NdasPortFdoDeviceControlEjectOrUnplugLogicalUnit(
	PNDASPORT_FDO_EXTENSION FdoExtension,
	PNDAS_LOGICALUNIT_ADDRESS LogicalUnitAddress,
	ULONG Flags,
	BOOLEAN Eject)
{
	NTSTATUS status;
	PNDASPORT_PDO_EXTENSION targetPdo;
	PLIST_ENTRY entry;

	PAGED_CODE();

	LogicalUnitAddress->PortNumber = FdoExtension->PortNumber;

	status = STATUS_DEVICE_DOES_NOT_EXIST;

	ExAcquireFastMutex (&FdoExtension->Mutex);

	for (entry = FdoExtension->ListOfPDOs.Flink;
		entry != &FdoExtension->ListOfPDOs;
		entry = entry->Flink) 
	{
		targetPdo = CONTAINING_RECORD(entry, NDASPORT_PDO_EXTENSION, Link);

		if (LogicalUnitAddress->Address == targetPdo->LogicalUnitAddress.Address)
		{
			//
			// Temporary pdo is regarded as none
			//
			if (targetPdo->IsTemporary)
			{
				status = STATUS_DEVICE_NOT_READY;
				break;
			}

			if (!targetPdo->IsDeviceRelationReported)
			{
				//
				// Pdo is not yet reported to Pnp bus relations.
				// If we call IoRequestDeviceEject before completing 
				// the bus relation query, it will lead pnp bug check.
				//
				status = STATUS_DEVICE_BUSY;
				break;
			}

			status = STATUS_SUCCESS;

			if (Eject)
			{
				// Nothing to do here
			}
			else
			{
				//
				// To be unplugged in the next invalidate device relations
				//
				targetPdo->Present = FALSE;
			}
			break;
		}
	}

	ExReleaseFastMutex (&FdoExtension->Mutex); 

	if (NT_SUCCESS(status))
	{
		if (Eject)
		{
			IoRequestDeviceEject(targetPdo->DeviceObject);
		}
		else
		{
			IoInvalidateDeviceRelations(
				FdoExtension->LowerPdo, 
				BusRelations);
		}
	}

	return status;
}
Beispiel #12
0
NTSTATUS
FDO_StartDevice(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp)
{
    NTSTATUS Status;
    PFDO_DEVICE_EXTENSION FDODeviceExtension;

    /* Get device extension */
    FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
    ASSERT(FDODeviceExtension->Common.IsFDO);

    /* First start lower device */
    Status = USBCCGP_SyncForwardIrp(FDODeviceExtension->NextDeviceObject, Irp);

    if (!NT_SUCCESS(Status))
    {
        /* Failed to start lower device */
        DPRINT1("FDO_StartDevice lower device failed to start with %x\n", Status);
        return Status;
    }

    /* Get descriptors */
    Status = USBCCGP_GetDescriptors(DeviceObject);
    if (!NT_SUCCESS(Status))
    {
        /* Failed to start lower device */
        DPRINT1("FDO_StartDevice failed to get descriptors with %x\n", Status);
        return Status;
    }

    /* Get capabilities */
    Status = FDO_QueryCapabilities(DeviceObject,
                                   &FDODeviceExtension->Capabilities);
    if (!NT_SUCCESS(Status))
    {
        /* Failed to start lower device */
        DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status);
        return Status;
    }

    /* Now select the configuration */
    Status = USBCCGP_SelectConfiguration(DeviceObject, FDODeviceExtension);
    if (!NT_SUCCESS(Status))
    {
        /* Failed to select interface */
        DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status);
        return Status;
    }

    /* Query bus interface */
    USBCCGP_QueryInterface(FDODeviceExtension->NextDeviceObject,
                           &FDODeviceExtension->BusInterface);

    /* Now enumerate the functions */
    Status = USBCCGP_EnumerateFunctions(DeviceObject);
    if (!NT_SUCCESS(Status))
    {
        /* Failed to enumerate functions */
        DPRINT1("Failed to enumerate functions with %x\n", Status);
        return Status;
    }

    /* Sanity checks */
    ASSERT(FDODeviceExtension->FunctionDescriptorCount);
    ASSERT(FDODeviceExtension->FunctionDescriptor);
    DumpFunctionDescriptor(FDODeviceExtension->FunctionDescriptor,
                           FDODeviceExtension->FunctionDescriptorCount);

    /* Now create the pdo */
    Status = FDO_CreateChildPdo(DeviceObject);
    if (!NT_SUCCESS(Status))
    {
        /* Failed */
        DPRINT1("FDO_CreateChildPdo failed with %x\n", Status);
        return Status;
    }

    /* Inform pnp manager of new device objects */
    IoInvalidateDeviceRelations(FDODeviceExtension->PhysicalDeviceObject,
                                BusRelations);

    /* Done */
    DPRINT("[USBCCGP] FDO initialized successfully\n");
    return Status;
}
Beispiel #13
0
VOID NTAPI
WorkerThread(IN PVOID Context)
{
    PHUB_DEVICE_EXTENSION DeviceExtension;
    PDEVICE_OBJECT DeviceObject, Pdo;
    PHUB_CHILDDEVICE_EXTENSION PdoExtension;
    PURB Urb = NULL;
    PORTSTATUSANDCHANGE PortStatusAndChange;
    int PortLoop, DeviceCount;
    NTSTATUS Status;
    USB_DEVICE_DESCRIPTOR DevDesc;
    USB_CONFIGURATION_DESCRIPTOR ConfigDesc;
    ULONG DevDescSize, ConfigDescSize;
    PUSB_STRING_DESCRIPTOR StringDesc;
    USB_STRING_DESCRIPTOR LanguageIdDescriptor;
    PWORKITEMDATA WorkItemData = (PWORKITEMDATA)Context;

    DeviceObject = (PDEVICE_OBJECT)WorkItemData->Context;

    DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    /* Determine where in the children array to store this device info */
    for (DeviceCount = 0; DeviceCount < USB_MAXCHILDREN; DeviceCount++)
    {
        if (DeviceExtension->UsbChildren[DeviceCount] == NULL)
        {
            break;
        }
    }

    Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB), USB_HUB_TAG);
    if (!Urb)
    {
        DPRINT1("Failed to allocate memory for URB!\n");
        ASSERT(FALSE);
    }

    RtlZeroMemory(Urb, sizeof(URB));

    for (PortLoop = 0; PortLoop < DeviceExtension->UsbExtHubInfo.NumberOfPorts; PortLoop++)
    {
        /* Get the port status */
        UsbBuildVendorRequest(Urb,
                            URB_FUNCTION_CLASS_OTHER,
                            sizeof(Urb->UrbControlVendorClassRequest),
                            USBD_TRANSFER_DIRECTION_OUT,
                            0,
                            USB_REQUEST_GET_STATUS,
                            0,
                            PortLoop + 1,
                            &PortStatusAndChange,
                            0,
                            sizeof(PORTSTATUSANDCHANGE),
                            0);

        Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Failed to get PortStatus!\n");
            goto CleanUp;
        }

        DPRINT("Notification Port %x:\n", PortLoop + 1);
        DPRINT("Status %x\n", PortStatusAndChange.Status);
        DPRINT("Change %x\n", PortStatusAndChange.Change);

        if (PortStatusAndChange.Change == USB_PORT_STATUS_RESET)
        {
            /* Clear the Reset */
            UsbBuildVendorRequest(Urb,
                                  URB_FUNCTION_CLASS_OTHER,
                                  sizeof(Urb->UrbControlVendorClassRequest),
                                  USBD_TRANSFER_DIRECTION_IN,
                                  0,
                                  USB_REQUEST_CLEAR_FEATURE,
                                  C_PORT_RESET,
                                  PortLoop + 1,
                                  &PortStatusAndChange,
                                  0,
                                  sizeof(PORTSTATUSANDCHANGE),
                                  0);

            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Failed to Clear the Port Reset with Status %x!\n", Status);
                goto CleanUp;
            }

            UsbBuildVendorRequest(Urb, URB_FUNCTION_CLASS_OTHER,
                                  sizeof(Urb->UrbControlVendorClassRequest),
                                  USBD_TRANSFER_DIRECTION_OUT,
                                  0,
                                  USB_REQUEST_GET_STATUS,
                                  0,
                                  PortLoop + 1,
                                  &PortStatusAndChange,
                                  0,
                                  sizeof(PORTSTATUSANDCHANGE),
                                  0);

            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);

            DPRINT("Status %x\n", PortStatusAndChange.Status);
            DPRINT("Change %x\n", PortStatusAndChange.Change);

            /* Create the UsbDevice */
            Status = DeviceExtension->HubInterface.CreateUsbDevice(DeviceExtension->RootHubPdo,
                                                                   (PVOID)&DeviceExtension->UsbChildren[DeviceCount],
                                                                   DeviceExtension->RootHubUsbDevice,
                                                                   PortStatusAndChange.Status,
                                                                   PortLoop + 1);
            DPRINT1("CreateUsbDevice Status %x\n", Status);

            Status = DeviceExtension->HubInterface.InitializeUsbDevice(DeviceExtension->RootHubPdo, DeviceExtension->UsbChildren[DeviceCount]);
            DPRINT1("InitializeUsbDevice Status %x\n", Status);

            DevDescSize = sizeof(USB_DEVICE_DESCRIPTOR);
            ConfigDescSize = sizeof(USB_CONFIGURATION_DESCRIPTOR);
            Status = DeviceExtension->HubInterface.GetUsbDescriptors(DeviceExtension->RootHubPdo,
                                                                     DeviceExtension->UsbChildren[DeviceCount],
                                                                     (PUCHAR)&DevDesc,
                                                                     &DevDescSize,
                                                                     (PUCHAR)&ConfigDesc,
                                                                     &ConfigDescSize);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Failed to Get Usb Deccriptors %x!\n", Status);
            }

            DumpDeviceDescriptor(&DevDesc);

            Status = IoCreateDevice(DeviceObject->DriverObject,
                                    sizeof(HUB_CHILDDEVICE_EXTENSION),
                                    NULL,
                                    FILE_DEVICE_CONTROLLER,
                                    FILE_AUTOGENERATED_DEVICE_NAME,
                                    FALSE,
                                    &DeviceExtension->Children[DeviceCount]);

            if (!NT_SUCCESS(Status))
            {
                DPRINT1("UsbHub; IoCreateDevice failed with status %x\n",Status);
                goto CleanUp;
            }

            Pdo = DeviceExtension->Children[DeviceCount];
            DPRINT1("Created New Device with %x\n", Pdo);
            Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;

            PdoExtension = Pdo->DeviceExtension;

            RtlZeroMemory(PdoExtension, sizeof(HUB_CHILDDEVICE_EXTENSION));

            PdoExtension->DeviceId = ExAllocatePoolWithTag(NonPagedPool, 32 * sizeof(WCHAR), USB_HUB_TAG);
            RtlZeroMemory(PdoExtension->DeviceId, 32 * sizeof(WCHAR));
            swprintf(PdoExtension->DeviceId, L"USB\\Vid_%04x&Pid_%04x", DevDesc.idVendor, DevDesc.idProduct);


            /* Get the LANGids */
            RtlZeroMemory(&LanguageIdDescriptor, sizeof(USB_STRING_DESCRIPTOR));
            UsbBuildGetDescriptorRequest(Urb,
                                         sizeof(Urb->UrbControlDescriptorRequest),
                                         USB_STRING_DESCRIPTOR_TYPE,
                                         0,
                                         0,
                                         &LanguageIdDescriptor,
                                         NULL,
                                         sizeof(USB_STRING_DESCRIPTOR),
                                         NULL);

            Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->UsbChildren[DeviceCount];
            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);

            /* Get the length of the SerialNumber */
            StringDesc = ExAllocatePoolWithTag(PagedPool, 64, USB_HUB_TAG);
            RtlZeroMemory(StringDesc, 64);
            StringDesc->bLength = 0;
            StringDesc->bDescriptorType = 0;

            UsbBuildGetDescriptorRequest(Urb,
                                         sizeof(Urb->UrbControlDescriptorRequest),
                                         USB_STRING_DESCRIPTOR_TYPE,
                                         DevDesc.iSerialNumber,
                                         LanguageIdDescriptor.bString[0],
                                         StringDesc,
                                         NULL,
                                         64,
                                         NULL);

            Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->UsbChildren[DeviceCount];

            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);

            PdoExtension->InstanceId = ExAllocatePoolWithTag(NonPagedPool, (StringDesc->bLength + 1) * sizeof(WCHAR), USB_HUB_TAG);
            DPRINT1("PdoExtension->InstanceId %x\n",PdoExtension->InstanceId);

            RtlZeroMemory(PdoExtension->InstanceId, (StringDesc->bLength + 1) * sizeof(WCHAR));
            RtlCopyMemory(PdoExtension->InstanceId, &StringDesc->bString[0], StringDesc->bLength);
            DPRINT1("------>SerialNumber %S\n", PdoExtension->InstanceId);



            RtlZeroMemory(StringDesc, 64);
            StringDesc->bLength = 0;
            StringDesc->bDescriptorType = 0;

            UsbBuildGetDescriptorRequest(Urb,
                                         sizeof(Urb->UrbControlDescriptorRequest),
                                         USB_STRING_DESCRIPTOR_TYPE,
                                         DevDesc.iProduct,
                                         LanguageIdDescriptor.bString[0],
                                         StringDesc,
                                         NULL,
                                         64,
                                         NULL);

            Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->UsbChildren[DeviceCount];

            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);

            PdoExtension->TextDescription = ExAllocatePoolWithTag(NonPagedPool, (StringDesc->bLength + 1) * sizeof(WCHAR), USB_HUB_TAG);

            RtlZeroMemory(PdoExtension->TextDescription, (StringDesc->bLength + 1) * sizeof(WCHAR));
            RtlCopyMemory(PdoExtension->TextDescription, &StringDesc->bString[0], StringDesc->bLength);
            ExFreePool(StringDesc);
            DPRINT1("------>TextDescription %S\n", PdoExtension->TextDescription);

            PdoExtension->IsFDO = FALSE;
            PdoExtension->Parent = DeviceObject;
            Pdo->Flags &= ~DO_DEVICE_INITIALIZING;

            ExFreePool(WorkItemData);
            ExFreePool(Urb);

            IoInvalidateDeviceRelations(DeviceExtension->RootHubPdo, BusRelations);
            return;
        }

        /* Is a device connected to this port */
        if (PortStatusAndChange.Change == USB_PORT_STATUS_CONNECT)
        {
            /* Clear the Connect from ProtChange */
            UsbBuildVendorRequest(Urb,
                                URB_FUNCTION_CLASS_OTHER,
                                sizeof(Urb->UrbControlVendorClassRequest),
                                USBD_TRANSFER_DIRECTION_IN,
                                0,
                                USB_REQUEST_CLEAR_FEATURE,
                                C_PORT_CONNECTION,
                                PortLoop + 1,
                                &PortStatusAndChange,
                                0,
                                sizeof(PORTSTATUSANDCHANGE),
                                0);

            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Failed to Clear the Port Connect!\n");
                goto CleanUp;
            }

            /* Send the miniport controller a SCE request so when the port resets we can be informed */
            WaitForUsbDeviceArrivalNotification(DeviceObject);

            UsbBuildVendorRequest(Urb,
                                URB_FUNCTION_CLASS_OTHER,
                                sizeof(Urb->UrbControlVendorClassRequest),
                                USBD_TRANSFER_DIRECTION_IN,
                                0,
                                USB_REQUEST_SET_FEATURE,
                                PORT_RESET,
                                PortLoop + 1,
                                &PortStatusAndChange,
                                0,
                                sizeof(PORTSTATUSANDCHANGE),
                                0);

            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);

            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Failed to Reset the port!\n");
                goto CleanUp;
            }
            /* At this point the miniport will complete another SCE to inform of Reset completed */
        }
    }

CleanUp:
    ExFreePool(WorkItemData);
    ExFreePool(Urb);
}
Beispiel #14
0
int body() {


   if( NT_SUCCESS( status ) ) {

       ExAcquireFastMutex();
       SetFlags();
       ExReleaseFastMutex();

       WarmPollPeriod = HtRegGetDword();
       if( WarmPollPeriod < 5 ) {
           WarmPollPeriod = 5;
       } else {
           if( WarmPollPeriod > 20 ) {
               WarmPollPeriod = 20;
           }
       }
       {


           if (nondet()) {

               // We've got it.  Now get a pointer to it.
               polling = 1;
               if(nondet()) {
//---------------------------------------------

               {
                   LARGE_INTEGER   timeOut1;
                   NTSTATUS        status;
                   UCHAR           deviceStatus;
                   PCHAR           devId;
                   BOOLEAN         requestRescan;
                   const ULONG     pollingFailureThreshold = 10; //pick an arbitrary but reasonable number

                   do {
                       if( PowerStateIsAC ) {
                       } else {
                       }
                       status = KeWaitForSingleObject();
                       if( nondet() ) {
                           break;
                       }
                       if( !PowerStateIsAC ) {
                           goto loc_continue;
                       }
                       if( STATUS_TIMEOUT == status ) {
                           if( nondet() ) {
                               // try to acquire port
                               if( HtTryAllocatePort() ) {
                                   requestRescan = FALSE;
                                   // check for something connected
                                   deviceStatus = GetStatus();
                                   if( nondet()) {
                                   } else {
                                       // we might have something connected
                                       // try a device ID to confirm
                                       devId = P4ReadRawIeee1284DeviceId();
                                       if( devId ) {
                                           PCHAR  mfg, mdl, cls, des, aid, cid;
                                           // RawIeee1284 string includes 2 bytes of length data at beginning
                                           HTPnpFindDeviceIdKeys();
                                           if( mfg && mdl ) {
                                               requestRescan = TRUE;
                                           }
                                       } else {
                                       }
                                       if( requestRescan ) {
                                       } else {
                                           if(nondet() ) {
                                           }
                                       }
                                   }
                                   HtFreePort( );
                                   if( requestRescan ) {
                                       IoInvalidateDeviceRelations();
                                   }

                               } else {
                               }

                           } else {
                           }

                       }
		   loc_continue: { int ddd; ddd = ddd; }
                   } while( TRUE );

               }

//---------------------------------------------
                   polling = 0;

               } else {

                   polling = 0;
                   // error

               }


           } else {
           }

       }

   }
   // Failsafe
   polling = 1;
   while (1) {
       HTPnpFindDeviceIdKeys();
   }
}
Beispiel #15
0
// device io control for bus fdo
NTSTATUS DispatchIoControl(PDEVICE_OBJECT pDevice,PIRP pIrp)
{
	NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;

	PFdoExt pFdoExt = static_cast<PFdoExt>(pDevice->DeviceExtension);

	if(pFdoExt->m_bFdo)
	{
		BOOLEAN bCallNext = TRUE;
		IncIoCount(pFdoExt);
		
		PIO_STACK_LOCATION pIoStack = IoGetCurrentIrpStackLocation(pIrp);
		switch(pIoStack->Parameters.DeviceIoControl.IoControlCode)
		{
			// add a scsi device,input is a miniport config struct
		case IOCTL_TIAMO_BUS_PLUGIN:
			status = STATUS_INVALID_PARAMETER;

			bCallNext = FALSE;

			if(pIoStack->Parameters.DeviceIoControl.InputBufferLength == sizeof(MiniportConfig))
			{
				PMiniportConfig pMiniportConfig = static_cast<PMiniportConfig>(pIrp->AssociatedIrp.SystemBuffer);

				if(pMiniportConfig && pMiniportConfig->m_ulDevices > 0 && pMiniportConfig->m_ulDevices < 5)
				{
					ExAcquireFastMutex(&pFdoExt->m_mutexEnumPdo);

					// create the only one pdo
					if(!pFdoExt->m_pEnumPdo)
					{
						PDEVICE_OBJECT pdo;
						status = IoCreateDevice(pDevice->DriverObject,sizeof(PdoExt),NULL,FILE_DEVICE_BUS_EXTENDER,
												FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,FALSE,&pdo);

						if(NT_SUCCESS(status))
						{
							// set the pdo ext
							PPdoExt pPdoExt = static_cast<PPdoExt>(pdo->DeviceExtension);

							RtlZeroMemory(pPdoExt,sizeof(PdoExt));

							pPdoExt->m_bFdo = FALSE;
							// save the fdo here
							pPdoExt->m_pParentFdo = pDevice;
							pPdoExt->m_ulCurrentPnpState = pPdoExt->m_ulPrevPnpState = -1;

							pPdoExt->m_sysPowerState = PowerSystemWorking;
							pPdoExt->m_devPowerState = PowerDeviceD3;
							pPdoExt->m_bPresent = TRUE;

							//pdo->Flags |= DO_POWER_PAGABLE;
							
							pFdoExt->m_pEnumPdo = pdo;

							RtlMoveMemory(pPdoExt->m_szImageFileName,pMiniportConfig->m_szImageFileName,1024 * sizeof(WCHAR));

							pPdoExt->m_ulDevices = pMiniportConfig->m_ulDevices;

							pdo->Flags &= ~DO_DEVICE_INITIALIZING;

							devDebugPrint(DRIVER_NAME"*******IOCTL_TIAMO_BUS_PLUGIN detected new device and created a pdo.\n");
						}
					}
					else
					{
						status = STATUS_DEVICE_ALREADY_ATTACHED;
					}

					ExReleaseFastMutex(&pFdoExt->m_mutexEnumPdo);

					if(NT_SUCCESS(status))
						IoInvalidateDeviceRelations(pFdoExt->m_pPhysicalDevice,BusRelations);
				}
			}
			break;

			// miniport get config
		case IOCTL_TIAMO_BUS_MINIPORT_GET_CONFIG:
			status = STATUS_INVALID_PARAMETER;

			bCallNext = FALSE;

			if(pIoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(MiniportConfig))
			{
				ExAcquireFastMutex(&pFdoExt->m_mutexEnumPdo);
				if(pFdoExt->m_pEnumPdo)
				{
					PPdoExt pPdoExt = static_cast<PPdoExt>(pFdoExt->m_pEnumPdo->DeviceExtension);
					if(pPdoExt)
					{
						RtlMoveMemory(pIrp->AssociatedIrp.SystemBuffer,&pPdoExt->m_ulDevices,sizeof(MiniportConfig));
						pIrp->IoStatus.Information = sizeof(MiniportConfig);
						status = STATUS_SUCCESS;
						devDebugPrint(DRIVER_NAME"*******IOCTL_TIAMO_BUS_MINIPORT_GET_CONFIG upper miniport fdo get it's pdo configuration\n");
					}
				}
				else
				{
					status = STATUS_NO_SUCH_DEVICE;
				}

				ExReleaseFastMutex(&pFdoExt->m_mutexEnumPdo);
			}
			
			break;
		}

		DecIoCount(pFdoExt);

		if(bCallNext)
			return IoCallDriver(pFdoExt->m_pLowerDevice,pIrp);
	}
		
	pIrp->IoStatus.Status = status;
	IoCompleteRequest(pIrp,IO_NO_INCREMENT);
	
	return status;
}
Beispiel #16
0
VOID
NdasPortBindingChangeHandler(
	__in TDI_PNP_OPCODE PnPOpcode,
	__in PUNICODE_STRING TransportName,
	__in PWSTR BindingList)
{
	PNDASPORT_DRIVER_EXTENSION driverExtension;

	PAGED_CODE();

	driverExtension = (PNDASPORT_DRIVER_EXTENSION) IoGetDriverObjectExtension(
		NdasPortDriverObject,
		&NdasPortDriverExtensionTag);

	ASSERT(NULL != driverExtension);

	DebugPrint((1, 
		"NdasPortBindingChangeHandler: PnPOpcode=%s(%x), TransportName=%wZ,\n", 
		DbgTdiPnpOpCodeString(PnPOpcode),
		PnPOpcode, 
		TransportName));

	NdasPortTrace(NDASPORT_GENERAL, TRACE_LEVEL_INFORMATION,
		"NdasPortBindingChangeHandler: PnpOpCode=%s(%x), TransportName=%wZ,\n",
		DbgTdiPnpOpCodeString(PnPOpcode),
		PnPOpcode,
		TransportName);

	switch (PnPOpcode) 
	{
	case TDI_PNP_OP_ADD:
	case TDI_PNP_OP_DEL:
	case TDI_PNP_OP_PROVIDERREADY:
		break;

	case TDI_PNP_OP_NETREADY:
		{
			BOOLEAN previouslyReady;

			previouslyReady = driverExtension->IsNetworkReady;
			driverExtension->IsNetworkReady = TRUE;

			//
			// State change from network "not ready" to
			// network "ready" state. Will initialize
			// device detection
			//
			if (previouslyReady == FALSE) 
			{
				KIRQL oldIrql;
				PLIST_ENTRY entry;
				DebugPrint((3, "Network is now ready!\n"));

				//
				// Request device enumeration request from PnP.
				//

				KeAcquireSpinLock(&driverExtension->FdoListSpinLock, &oldIrql);
				for (entry = driverExtension->FdoList.Flink;
					entry != &driverExtension->FdoList;
					entry = entry->Flink) 
				{
					PNDASPORT_FDO_EXTENSION fdoExtension;
					fdoExtension = CONTAINING_RECORD(entry, NDASPORT_FDO_EXTENSION, Link);
					IoInvalidateDeviceRelations(
						fdoExtension->LowerPdo,
						BusRelations);
				}
				KeReleaseSpinLock(&driverExtension->FdoListSpinLock, oldIrql);
			}

			break;
		}
	default: 
		{
			break;
		}
	}

	return;
}