Esempio n. 1
0
NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pUsRegPath)
{
    UCHAR  ucCnt = 0;

    DkDbgStr("3");

    pDrvObj->DriverUnload                = DkUnload;
    pDrvObj->DriverExtension->AddDevice  = AddDevice;

    for (ucCnt = 0; ucCnt < IRP_MJ_MAXIMUM_FUNCTION; ucCnt++)
    {
        pDrvObj->MajorFunction[ucCnt] = DkDefault;
    }

    pDrvObj->MajorFunction[IRP_MJ_CREATE] =
        pDrvObj->MajorFunction[IRP_MJ_CLEANUP] =
        pDrvObj->MajorFunction[IRP_MJ_CLOSE]   = DkCreateClose;

    pDrvObj->MajorFunction[IRP_MJ_READ] =
        pDrvObj->MajorFunction[IRP_MJ_WRITE] = DkReadWrite;

    pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DkDevCtl;

    pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = DkInDevCtl;

    pDrvObj->MajorFunction[IRP_MJ_PNP] = DkPnP;

    pDrvObj->MajorFunction[IRP_MJ_POWER]                    = DkPower;

    g_controlId = (ULONG)0;

    return STATUS_SUCCESS;
}
Esempio n. 2
0
/*
 * Writes data to buffer.
 *
 * Caller must have acquired buffer spin lock.
 */
static NTSTATUS USBPcapBufferWrite(PUSBPCAP_ROOTHUB_DATA pData,
                                   PVOID data,
                                   UINT32 length)
{
    if (length == 0)
    {
        DkDbgStr("Cannot write empty data.");
        return STATUS_INVALID_PARAMETER;
    }

    if (USBPcapGetBufferFree(pData) < length)
    {
        DkDbgStr("No free space left.");
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    USBPcapBufferWriteUnsafe(pData, data, length);
    return STATUS_SUCCESS;
}
Esempio n. 3
0
NTSTATUS USBPcapBufferWritePacket(PUSBPCAP_ROOTHUB_DATA pRootData,
                                  PUSBPCAP_BUFFER_PACKET_HEADER header,
                                  PVOID buffer)
{
    UINT32             bytes;
    UINT32             bytesFree;
    KIRQL              irql;
    NTSTATUS           status;
    PDEVICE_EXTENSION  pControlExt;
    PIRP               pIrp = NULL;
    pcaprec_hdr_t      pcapHeader;

    pControlExt = (PDEVICE_EXTENSION)pRootData->controlDevice->DeviceExtension;

    ASSERT(pControlExt->deviceMagic == USBPCAP_MAGIC_CONTROL);

    bytes = header->headerLen + header->dataLength;

    KeAcquireSpinLock(&pRootData->bufferLock, &irql);

    USBPcapInitializePcapHeader(pRootData, &pcapHeader, bytes);

    /* pcapHeader.incl_len contains the number of bytes to write */
    bytes = pcapHeader.incl_len;

    status = STATUS_SUCCESS;

    bytesFree = USBPcapGetBufferFree(pRootData);

    if ((pRootData->buffer == NULL) ||
        (bytesFree < sizeof(pcaprec_hdr_t)) ||
        ((bytesFree - sizeof(pcaprec_hdr_t)) < bytes))
    {
        DkDbgStr("No enough free space left.");
        status = STATUS_INSUFFICIENT_RESOURCES;
    }
    else
    {
        UINT32 tmp;

        /* Write Packet Header */
        USBPcapBufferWriteUnsafe(pRootData,
                                 (PVOID) &pcapHeader,
                                 (UINT32) sizeof(pcaprec_hdr_t));

        /* Write USBPCAP_BUFFER_PACKET_HEADER */
        tmp = min(bytes, (UINT32)header->headerLen);
        if (tmp > 0)
        {
            USBPcapBufferWriteUnsafe(pRootData,
                                     (PVOID) header,
                                     tmp);
        }
        bytes -= tmp;

        if (bytes > 0 && header->dataLength > 0)
        {
            /* Write data */
            tmp = min(bytes, header->dataLength);
            USBPcapBufferWriteUnsafe(pRootData,
                                     buffer,
                                     tmp);
        }
    }
    KeReleaseSpinLock(&pRootData->bufferLock, irql);

    if (NT_SUCCESS(status))
    {
        pIrp = IoCsqRemoveNextIrp(&pControlExt->context.control.ioCsq,
                                  NULL);
        if (pIrp != NULL)
        {
            PVOID   buffer;
            UINT32  bufferLength;
            UINT32  bytesRead;

            /*
             * Only IRPs with non-zero buffer are being queued.
             *
             * Since control device has DO_DIRECT_IO bit set the MDL is already
             * probed and locked
             */
            buffer = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress,
                                                  NormalPagePriority);

            if (buffer == NULL)
            {
                pIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
                bytes = 0;
            }
            else
            {
                UINT32 bufferLength = MmGetMdlByteCount(pIrp->MdlAddress);

                if (bufferLength != 0)
                {
                    KeAcquireSpinLock(&pRootData->bufferLock, &irql);
                    bytes = USBPcapBufferRead(pRootData,
                                              buffer, bufferLength);
                    KeReleaseSpinLock(&pRootData->bufferLock, irql);
                }
                else
                {
                    bytes = 0;
                }

                pIrp->IoStatus.Status = STATUS_SUCCESS;
            }

            pIrp->IoStatus.Information = (ULONG_PTR) bytes;
            IoCompleteRequest(pIrp, IO_NO_INCREMENT);
        }
    }

    return status;
}
Esempio n. 4
0
NTSTATUS DkHubFltPnP(PDEVICE_EXTENSION pDevExt, PIO_STACK_LOCATION pStack, PIRP pIrp)
{
    NTSTATUS  ntStat = STATUS_SUCCESS;

    ntStat = IoAcquireRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);
    if (!NT_SUCCESS(ntStat))
    {
        DkDbgVal("Error lock!", ntStat);
        DkCompleteRequest(pIrp, ntStat, 0);
        return ntStat;
    }

    switch (pStack->MinorFunction)
    {
        case IRP_MN_START_DEVICE:
            DkDbgStr("IRP_MN_START_DEVICE");

            ntStat = DkForwardAndWait(pDevExt->pNextDevObj, pIrp);
            IoCompleteRequest(pIrp, IO_NO_INCREMENT);
            IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);

            return ntStat;

        case IRP_MN_REMOVE_DEVICE:
        {
            PUSBPCAP_DEVICE_DATA pDeviceData = pDevExt->context.usb.pDeviceData;
            DkDbgStr("IRP_MN_REMOVE_DEVICE");

            IoSkipCurrentIrpStackLocation(pIrp);
            ntStat = IoCallDriver(pDevExt->pNextDevObj, pIrp);

            if (pDeviceData != NULL &&
                pDeviceData->pRootData != NULL &&
                pDeviceData->pRootData->controlDevice != NULL)
            {
                USBPcapDeleteRootHubControlDevice(pDeviceData->pRootData->controlDevice);
            }

            IoReleaseRemoveLockAndWait(&pDevExt->removeLock, (PVOID) pIrp);

            DkDetachAndDeleteHubFilt(pDevExt);

            return ntStat;
        }

        case IRP_MN_QUERY_DEVICE_RELATIONS:
            DkDbgStr("IRP_MN_QUERY_DEVICE_RELATIONS");
            ntStat = DkHubFltPnpHandleQryDevRels(pDevExt, pStack, pIrp);

            IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);
            return ntStat;

        default:
            DkDbgVal("", pStack->MinorFunction);
            break;

    }

    IoSkipCurrentIrpStackLocation(pIrp);
    ntStat = IoCallDriver(pDevExt->pNextDevObj, pIrp);

    IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);

    return ntStat;
}
Esempio n. 5
0
NTSTATUS DkHubFltPnpHandleQryDevRels(PDEVICE_EXTENSION pDevExt, PIO_STACK_LOCATION pStack, PIRP pIrp)
{
    NTSTATUS             ntStat = STATUS_SUCCESS;
    PDEVICE_RELATIONS    pDevRel = NULL;
    PUSBPCAP_DEVICE_DATA pDeviceData = pDevExt->context.usb.pDeviceData;
    ULONG                i;

    ntStat = IoAcquireRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);
    if (!NT_SUCCESS(ntStat))
    {
        DkDbgVal("Error lock!", ntStat);
        DkCompleteRequest(pIrp, ntStat, 0);
        return ntStat;
    }

    /* PnP manager sends this at PASSIVE_LEVEL */
    switch (pStack->Parameters.QueryDeviceRelations.Type)
    {
        case BusRelations:
            DkDbgStr("PnP, IRP_MN_QUERY_DEVICE_RELATIONS: BusRelations");

            ntStat = DkForwardAndWait(pDevExt->pNextDevObj, pIrp);

            // After we forward the request, the bus driver have created or deleted
            // a child device object. When bus driver created one (or more), this is the PDO
            // of our target device, we create and attach a filter object to it.
            // Note that we only attach the last detected USB device on it's Hub.
            if (NT_SUCCESS(ntStat))
            {
                pDevRel = (PDEVICE_RELATIONS) pIrp->IoStatus.Information;
                if (pDevRel)
                {
                    USBPcapPrintUSBPChildrenInformation(pDevExt->pNextDevObj);

                    DkDbgVal("Child(s) number", pDevRel->Count);

                    for (i = 0; i < pDevRel->Count; i++)
                    {
                        PDEVICE_OBJECT *child;
                        BOOLEAN        found = FALSE;

                        child = pDeviceData->previousChildren;

                        /* Search only if there are any children */
                        if (child != NULL)
                        {
                            while (*child != NULL)
                            {
                                if (*child == pDevRel->Objects[i])
                                {
                                    found = TRUE;
                                    break;
                                }
                                child++;
                            }
                        }

                        if (found == FALSE)
                        {
                            /* New device attached */
                            DkCreateAndAttachTgt(pDevExt,
                                                 pDevRel->Objects[i]);
                        }
                    }

                    /* Free old children information */
                    if (pDeviceData->previousChildren != NULL)
                    {
                        ExFreePool(pDeviceData->previousChildren);
                        pDeviceData->previousChildren = NULL;
                    }

                    if (pDevRel->Count > 0)
                    {
                        PDEVICE_OBJECT *children;

                        children =
                            ExAllocatePoolWithTag(NonPagedPool,
                                                  sizeof(PDEVICE_OBJECT) *
                                                  (pDevRel->Count + 1),
                                                  DKPORT_MTAG);

                        if (children != NULL)
                        {
                            for (i = 0; i < pDevRel->Count; i++)
                            {
                                children[i] = pDevRel->Objects[i];
                            }

                            /* NULL-terminate the array */
                            children[pDevRel->Count] = NULL;

                            pDeviceData->previousChildren = children;
                        }
                        else
                        {
                            /* Failed to allocate memory. Just leave it
                             * as it. In next pass we won't check for
                             * new devices (probably will miss some).
                             * But it's probably the best we can do.
                             */
                            DkDbgStr("Failed to allocate previousChildren");
                        }
                    }
                }
            }

            IoCompleteRequest(pIrp, IO_NO_INCREMENT);

            IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);

            return ntStat;


        case EjectionRelations:
            DkDbgStr("PnP, IRP_MN_QUERY_DEVICE_RELATIONS: EjectionRelations");
            break;
        case RemovalRelations:
            DkDbgStr("PnP, IRP_MN_QUERY_DEVICE_RELATIONS: RemovalRelations");
            break;
        case TargetDeviceRelation:
            DkDbgStr("PnP, IRP_MN_QUERY_DEVICE_RELATIONS: TargetDeviceRelation");
            break;
        case PowerRelations:
            DkDbgStr("PnP, IRP_MN_QUERY_DEVICE_RELATIONS: PowerRelations");
            break;
        case SingleBusRelations:
            DkDbgStr("PnP, IRP_MN_QUERY_DEVICE_RELATIONS: SingleBusRelations");
            break;
        case TransportRelations:
            DkDbgStr("PnP, IRP_MN_QUERY_DEVICE_RELATIONS: TransportRelations");
            break;

        default:
            DkDbgStr("PnP, IRP_MN_QUERY_DEVICE_RELATIONS: Unknown query relation type");
            break;
    }

    IoSkipCurrentIrpStackLocation(pIrp);
    ntStat = IoCallDriver(pDevExt->pNextDevObj, pIrp);

    IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);

    return ntStat;
}
Esempio n. 6
0
NTSTATUS DkTgtPnP(PDEVICE_EXTENSION pDevExt, PIO_STACK_LOCATION pStack, PIRP pIrp)
{
    NTSTATUS             ntStat = STATUS_SUCCESS;
    PUSBPCAP_DEVICE_DATA  pDeviceData = pDevExt->context.usb.pDeviceData;

    ntStat = IoAcquireRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);
    if (!NT_SUCCESS(ntStat))
    {
        DkDbgVal("Error lock!", ntStat);
        DkCompleteRequest(pIrp, ntStat, 0);
        return ntStat;
    }

    switch (pStack->MinorFunction)
    {
        case IRP_MN_START_DEVICE:
            /* IRP_MN_START_DEVICE is sent at PASSIVE_LEVEL */
            DkDbgStr("IRP_MN_START_DEVICE");

            ntStat = DkForwardAndWait(pDevExt->pNextDevObj, pIrp);
            IoCompleteRequest(pIrp, IO_NO_INCREMENT);

            if (NT_SUCCESS(USBPcapGetDeviceUSBInfo(pDevExt)))
            {
                DkDbgVal("Started device", pDeviceData->deviceAddress);
            }
            else
            {
                DkDbgStr("Failed to get info of started device");
            }
            IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);
            return ntStat;

        case IRP_MN_QUERY_DEVICE_RELATIONS:
            /* Keep track of, and create child devices only for hubs.
             * Do not create child filters for composite devices.
             */
            if (pDeviceData->isHub == TRUE)
            {
                DkDbgStr("IRP_MN_QUERY_DEVICE_RELATIONS");
                ntStat = DkHubFltPnpHandleQryDevRels(pDevExt, pStack, pIrp);

                IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);
                return ntStat;
            }
            else
            {
                break;
            }

        case IRP_MN_REMOVE_DEVICE:
            DkDbgStr("IRP_MN_REMOVE_DEVICE");

            IoSkipCurrentIrpStackLocation(pIrp);
            ntStat = IoCallDriver(pDevExt->pNextDevObj, pIrp);

            IoReleaseRemoveLockAndWait(&pDevExt->removeLock, (PVOID) pIrp);

            DkDetachAndDeleteTgt(pDevExt);

            return ntStat;


        default:
            DkDbgVal("", pStack->MinorFunction);
            break;

    }

    IoSkipCurrentIrpStackLocation(pIrp);
    ntStat = IoCallDriver(pDevExt->pNextDevObj, pIrp);

    IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);

    return ntStat;
}
Esempio n. 7
0
VOID DkUnload(PDRIVER_OBJECT pDrvObj)
{
    DkDbgStr("2");
}
Esempio n. 8
0
////////////////////////////////////////////////////////////////////////////
// Functions to attach and detach target device object
//
NTSTATUS DkCreateAndAttachTgt(PDEVICE_EXTENSION pParentDevExt, PDEVICE_OBJECT pTgtDevObj)
{
    NTSTATUS           ntStat = STATUS_SUCCESS;
    PDEVICE_OBJECT     pDeviceObject = NULL;
    PDEVICE_EXTENSION  pDevExt = NULL;

    // 1. Create filter object for target device object
    ntStat = IoCreateDevice(pParentDevExt->pDrvObj,
                            sizeof(DEVICE_EXTENSION), NULL,
                            pTgtDevObj->DeviceType, 0,
                            FALSE, &pDeviceObject);
    if (!NT_SUCCESS(ntStat))
    {
        DkDbgVal("Error create target device!", ntStat);
        return ntStat;
    }

    if (pDeviceObject == NULL)
    {
        DkDbgStr("IoCreateDevice() succeeded but pDeviceObject was not set.");
        return ntStat;
    }

    pDevExt = (PDEVICE_EXTENSION) pDeviceObject->DeviceExtension;
    pDevExt->deviceMagic = USBPCAP_MAGIC_DEVICE;
    pDevExt->pThisDevObj = pDeviceObject;
    pDevExt->parentRemoveLock = &pParentDevExt->removeLock;
    pDevExt->pDrvObj = pParentDevExt->pDrvObj;

    ntStat = USBPcapAllocateDeviceData(pDevExt, pParentDevExt);
    if (!NT_SUCCESS(ntStat))
    {
        goto EndAttDev;
    }

    // 2. Initilize remove lock for filter object of target device
    IoInitializeRemoveLock(&pDevExt->removeLock, 0, 0, 0);

    // 3. Attach to target device
    pDevExt->pNextDevObj = NULL;
    pDevExt->pNextDevObj = IoAttachDeviceToDeviceStack(pDevExt->pThisDevObj, pTgtDevObj);
    if (pDevExt->pNextDevObj == NULL)
    {
        DkDbgStr("Error attach target device!");
        ntStat = STATUS_NO_SUCH_DEVICE;
        goto EndAttDev;
    }


    // 4. Set up some filter device object flags
    pDevExt->pThisDevObj->Flags |=
        (pDevExt->pNextDevObj->Flags & (DO_BUFFERED_IO | DO_POWER_PAGABLE | DO_DIRECT_IO));
    pDevExt->pThisDevObj->Flags &= ~DO_DEVICE_INITIALIZING;

    IoAcquireRemoveLock(pDevExt->parentRemoveLock, NULL);

EndAttDev:
    if (!NT_SUCCESS(ntStat))
    {
        USBPcapFreeDeviceData(pDevExt);
        if (pDeviceObject)
        {
            IoDeleteDevice(pDeviceObject);
            pDeviceObject = NULL;
        }
    }

    return ntStat;
}
Esempio n. 9
0
NTSTATUS AddDevice(IN PDRIVER_OBJECT pDrvObj,
                   IN PDEVICE_OBJECT pTgtDevObj)
{
    NTSTATUS          ntStat = STATUS_SUCCESS;
    UNICODE_STRING    usTgtName;
    PDEVICE_OBJECT    pHubFilter = NULL;
    PDEVICE_EXTENSION pDevExt = NULL;
    BOOLEAN           isRootHub;

    // 1. Check if device is Root Hub
    isRootHub = USBPcapIsDeviceRootHub(pTgtDevObj);
    if (isRootHub == FALSE)
    {
        /* Do not attach to non-RootHub devices */
        return STATUS_SUCCESS;
    }

    // 2. Create filter object
    ntStat = IoCreateDevice(pDrvObj,
                            sizeof(DEVICE_EXTENSION), NULL,
                            GetDeviceTypeToUse(pTgtDevObj), 0,
                            FALSE, &pHubFilter);
    if (!NT_SUCCESS(ntStat))
    {
        DkDbgVal("Error create Hub Filter!", ntStat);
        goto EndFunc;
    }

    pDevExt = (PDEVICE_EXTENSION) pHubFilter->DeviceExtension;
    pDevExt->deviceMagic = USBPCAP_MAGIC_ROOTHUB;
    pDevExt->pThisDevObj = pHubFilter;
    pDevExt->pDrvObj = pDrvObj;
    pDevExt->parentRemoveLock = NULL;

    IoInitializeRemoveLock(&pDevExt->removeLock, 0, 0, 0);

    ntStat = USBPcapAllocateDeviceData(pDevExt, NULL);
    if (!NT_SUCCESS(ntStat))
    {
        goto EndFunc;
    }

    // 3. Attach to bus driver
    pDevExt->pNextDevObj = NULL;
    pDevExt->pNextDevObj = IoAttachDeviceToDeviceStack(pHubFilter, pTgtDevObj);
    if (pDevExt->pNextDevObj == NULL)
    {
        ntStat = STATUS_NO_SUCH_DEVICE;
        DkDbgStr("Error attach device!");
        goto EndFunc;
    }

    pHubFilter->Flags |=
        (pDevExt->pNextDevObj->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE));

    pHubFilter->Flags &= ~DO_DEVICE_INITIALIZING;

    if (NT_SUCCESS(ntStat))
    {
        PDEVICE_OBJECT         control = NULL;
        PUSBPCAP_ROOTHUB_DATA  pRootData;
        USHORT                 id;

        ntStat = USBPcapCreateRootHubControlDevice(pDevExt,
                                                   &control,
                                                   &id);

        pRootData = pDevExt->context.usb.pDeviceData->pRootData;
        pRootData->controlDevice = control;
        pRootData->busId = id;
    }

EndFunc:

    // If something bad happened
    if (!NT_SUCCESS(ntStat))
    {
        USBPcapFreeDeviceData(pDevExt);
        if (pHubFilter)
        {
            IoDeleteDevice(pHubFilter);
            pHubFilter = NULL;
        }
    }

    return ntStat;
}