⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isochapi.c

📁 winddk src目录下的WDM源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
    TRACE(TL_TRACE, ("hResource = 0x%x\n", hResource));
    TRACE(TL_TRACE, ("nNumberOfDescriptors = 0x%x\n", nNumberOfDescriptors));
    TRACE(TL_TRACE, ("R3_IsochDescriptor = 0x%x\n", R3_IsochDescriptor));

    if(!nNumberOfDescriptors)
    {
        TRACE(TL_WARNING, ("IsochAttachBuffers: Invalid nNumberOfDescriptors = 0x%x\n", nNumberOfDescriptors));
        ntStatus = STATUS_INVALID_PARAMETER;
        goto Exit_IsochAttachBuffers;
    }

    //
    // Just assume that we are being passed a Irp that was created in UserMode
    // and allocate one here, because we need to keep an Irp around for
    // the callback routine.  Must submit this asynchronously so use IoAllocateIrp
    //
    StackSize = deviceExtension->StackDeviceObject->StackSize;
    newIrp = IoAllocateIrp (StackSize, FALSE);

    if (!newIrp) {

        TRACE(TL_ERROR, ("Failed to allocate newIrp!\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit_IsochAttachBuffers;            
    }

    //
    // allocate the irb
    //
    pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));

    if (!pIrb) {

        TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit_IsochAttachBuffers;
    } // if

    //
    // allocate our isoch descriptors
    //
    pIsochDescriptor = ExAllocatePool(NonPagedPool, sizeof(ISOCH_DESCRIPTOR)*nNumberOfDescriptors);

    if (!pIsochDescriptor) {

        TRACE(TL_ERROR, ("Failed to allocate pIsochDescriptor!\n"));
        if (pIrb)
            ExFreePool(pIrb);

        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit_IsochAttachBuffers;
    }

    pR3TempDescriptor = R3_IsochDescriptor;
    for (i=0;i < nNumberOfDescriptors; i++) {

        TRACE(TL_TRACE, ("pR3TempDescriptor = 0x%x\n", pR3TempDescriptor));
        TRACE(TL_TRACE, ("pR3TempDescriptor->fulFlags = 0x%x\n", pR3TempDescriptor->fulFlags));
        TRACE(TL_TRACE, ("pR3TempDescriptor->ulLength = 0x%x\n", pR3TempDescriptor->ulLength));
        TRACE(TL_TRACE, ("pR3TempDescriptor->nMaxBytesPerFrame = 0x%x\n", pR3TempDescriptor->nMaxBytesPerFrame));
        TRACE(TL_TRACE, ("pR3TempDescriptor->ulSynch = 0x%x\n", pR3TempDescriptor->ulSynch));
        TRACE(TL_TRACE, ("pR3TempDescriptor->ulTag = 0x%x\n", pR3TempDescriptor->ulTag));
        TRACE(TL_TRACE, ("pR3TempDescriptor->CycleTime.CL_CycleOffset = 0x%x\n", pR3TempDescriptor->CycleTime.CL_CycleOffset));
        TRACE(TL_TRACE, ("pR3TempDescriptor->CycleTime.CL_CycleCount = 0x%x\n", pR3TempDescriptor->CycleTime.CL_CycleCount));
        TRACE(TL_TRACE, ("pR3TempDescriptor->CycleTime.CL_SecondCount = 0x%x\n", pR3TempDescriptor->CycleTime.CL_SecondCount));
        TRACE(TL_TRACE, ("pR3TempDescriptor->Data = 0x%x\n", &pR3TempDescriptor->Data));

        TRACE(TL_TRACE, ("pIsochDescriptor[%x] = 0x%x\n", i, &pIsochDescriptor[i]));

        // if we have a ulLength, create the Mdl. if not, Mdl=NULL
        if (pR3TempDescriptor->ulLength) {

            pIsochDescriptor[i].Mdl = IoAllocateMdl (pR3TempDescriptor->Data,
                                                     pR3TempDescriptor->ulLength,
                                                     FALSE,
                                                     FALSE,
                                                     NULL);

            
			if (!pIsochDescriptor[i].Mdl)
			{
				// we failed to alloc our mdl for this descriptor, free the previosly alloc'd mdls, and exit
				TRACE(TL_WARNING, ("Failed to allocate MDL for isoch descriptor num = 0x%x\n", i));
			
				for (j = 0; j < i; j++)
				{
					if (pIsochDescriptor[j].Mdl)
					{
						IoFreeMdl (pIsochDescriptor[j].Mdl);
					}
				}
				ExFreePool(pIsochDescriptor);
				ntStatus = STATUS_INVALID_PARAMETER;
				goto Exit_IsochAttachBuffers;
			}
			
			MmBuildMdlForNonPagedPool(pIsochDescriptor[i].Mdl);
            pIsochDescriptor[i].ulLength = MmGetMdlByteCount(pIsochDescriptor[i].Mdl);
        }
        else {

            pIsochDescriptor[i].Mdl = NULL;
            pIsochDescriptor[i].ulLength = pR3TempDescriptor->ulLength;
        }

        pIsochDescriptor[i].fulFlags = pR3TempDescriptor->fulFlags;
        pIsochDescriptor[i].nMaxBytesPerFrame = pR3TempDescriptor->nMaxBytesPerFrame;
        pIsochDescriptor[i].ulSynch = pR3TempDescriptor->ulSynch;
        pIsochDescriptor[i].ulTag = pR3TempDescriptor->ulTag;
        pIsochDescriptor[i].CycleTime = pR3TempDescriptor->CycleTime;

        if (pR3TempDescriptor->bUseCallback) {

            //
            // i'm hoping this is the last descriptor. they should have only set this in the
            // last descriptor, since elsewhere it's not supported.
            //
            if (i != nNumberOfDescriptors-1) {

                TRACE(TL_TRACE, ("Callback on descriptor prior to last!\n"));

                // setting callback to NULL
                pIsochDescriptor[i].Callback = NULL;
            }
            else {

                // need to save hResource, numDescriptors and Irp to use when detaching.
                // this needs to be done before we submit the irp, since the isoch callback
                // can be called before the submitirpsynch call completes.
                pIsochDetachData = ExAllocatePool(NonPagedPool, sizeof(ISOCH_DETACH_DATA));

                if (!pIsochDetachData)
                {
					for (j = 0; j < i; j++)
					{
						if (pIsochDescriptor[j].Mdl)
						{
							IoFreeMdl (pIsochDescriptor[j].Mdl);
						}
					}

                    TRACE(TL_ERROR, ("Failed to allocate pIsochDetachData!\n"));
                    ExFreePool(pIsochDescriptor);
                    ntStatus = STATUS_INSUFFICIENT_RESOURCES;                    
                    goto Exit_IsochAttachBuffers;
                }

                pIsochDetachData->AttachIrb = pIrb;

				KeAcquireSpinLock(&deviceExtension->IsochSpinLock, &Irql);
                InsertHeadList(&deviceExtension->IsochDetachData, &pIsochDetachData->IsochDetachList);
				KeReleaseSpinLock(&deviceExtension->IsochSpinLock, Irql);

                KeInitializeTimer(&pIsochDetachData->Timer);
                KeInitializeDpc(&pIsochDetachData->TimerDpc, t1394_IsochTimeout, pIsochDetachData);

                deltaTime.LowPart = ISOCH_DETACH_TIMEOUT_VALUE;
                deltaTime.HighPart = -1;
                KeSetTimer(&pIsochDetachData->Timer, deltaTime, &pIsochDetachData->TimerDpc);

                pIsochDetachData->outputBufferLength = outputBufferLength;
                pIsochDetachData->DeviceExtension = deviceExtension;
                pIsochDetachData->hResource = hResource;
                pIsochDetachData->numIsochDescriptors = nNumberOfDescriptors;
                pIsochDetachData->IsochDescriptor = pIsochDescriptor;
                pIsochDetachData->Irp = Irp;
                pIsochDetachData->newIrp = newIrp;
                pIsochDetachData->bDetach = pR3TempDescriptor->bAutoDetach;

                pIsochDescriptor[i].Callback = t1394_IsochCallback;

                pIsochDescriptor[i].Context1 = deviceExtension;
                pIsochDescriptor[i].Context2 = pIsochDetachData;

                TRACE(TL_TRACE, ("IsochAttachBuffers: pIsochDetachData = 0x%x\n", pIsochDetachData));
                TRACE(TL_TRACE, ("IsochAttachBuffers: pIsochDetachData->Irp = 0x%x\n", pIsochDetachData->Irp));
            }
        }
        else {

            pIsochDescriptor[i].Callback = NULL;
        }

        TRACE(TL_TRACE, ("pIsochDescriptor[%x].fulFlags = 0x%x\n", i, pIsochDescriptor[i].fulFlags));
        TRACE(TL_TRACE, ("pIsochDescriptor[%x].ulLength = 0x%x\n", i, pIsochDescriptor[i].ulLength));
        TRACE(TL_TRACE, ("pIsochDescriptor[%x].nMaxBytesPerFrame = 0x%x\n", i, pIsochDescriptor[i].nMaxBytesPerFrame));
        TRACE(TL_TRACE, ("pIsochDescriptor[%x].ulSynch = 0x%x\n", i, pIsochDescriptor[i].ulSynch));
        TRACE(TL_TRACE, ("pIsochDescriptor[%x].ulTag = 0x%x\n", i, pIsochDescriptor[i].ulTag));
        TRACE(TL_TRACE, ("pIsochDescriptor[%x].CycleTime.CL_CycleOffset = 0x%x\n", i, pIsochDescriptor[i].CycleTime.CL_CycleOffset));
        TRACE(TL_TRACE, ("pIsochDescriptor[%x].CycleTime.CL_CycleCount = 0x%x\n", i, pIsochDescriptor[i].CycleTime.CL_CycleCount));
        TRACE(TL_TRACE, ("pIsochDescriptor[%x].CycleTime.CL_SecondCount = 0x%x\n", i, pIsochDescriptor[i].CycleTime.CL_SecondCount));

        pR3TempDescriptor =
           (PRING3_ISOCH_DESCRIPTOR)((ULONG_PTR)pR3TempDescriptor +
                                     pIsochDescriptor[i].ulLength +
                                     sizeof(RING3_ISOCH_DESCRIPTOR));
    } // for

    // lets make sure the device is still around
    // if it isn't, we free the irb and return, our pnp
    // cleanup will take care of everything else
    if (deviceExtension->bShutdown) {

        TRACE(TL_TRACE, ("Shutdown!\n"));
        ntStatus = STATUS_NO_SUCH_DEVICE;
        goto Exit_IsochAttachBuffers;
    }

    RtlZeroMemory (pIrb, sizeof (IRB));
    pIrb->FunctionNumber = REQUEST_ISOCH_ATTACH_BUFFERS;
    pIrb->Flags = 0;
    pIrb->u.IsochAttachBuffers.hResource = hResource;
    pIrb->u.IsochAttachBuffers.nNumberOfDescriptors = nNumberOfDescriptors;
    pIrb->u.IsochAttachBuffers.pIsochDescriptor = pIsochDescriptor;

    // mark our original irp pending
    IoMarkIrpPending(Irp);
    
    //
    // Submit the newIrp directly to the driver below us
    //
    NextIrpStack = IoGetNextIrpStackLocation(newIrp);
    NextIrpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
    NextIrpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_1394_CLASS;
    NextIrpStack->Parameters.Others.Argument1 = pIrb; 

    IoSetCompletionRoutine( newIrp,
                            t1394_IsochAttachCompletionRoutine,
                            pIsochDetachData,
                            TRUE,
                            TRUE,
                            TRUE
                            );

    IoCallDriver(deviceExtension->StackDeviceObject, newIrp);
    ntStatus = STATUS_PENDING;
    
Exit_IsochAttachBuffers:

    EXIT("t1394_IsochAttachBuffers", ntStatus);
    return(ntStatus);
} // t1394_IsochAttachBuffers

NTSTATUS
t1394_IsochDetachBuffers(
    IN PDEVICE_OBJECT       DeviceObject,
    IN PIRP                 Irp,
    IN HANDLE               hResource,
    IN ULONG                nNumberOfDescriptors,
    IN PISOCH_DESCRIPTOR    IsochDescriptor
    )
{
    NTSTATUS            ntStatus        = STATUS_SUCCESS;
    PDEVICE_EXTENSION   deviceExtension = DeviceObject->DeviceExtension;
    PIRB                pIrb            = NULL;
    ULONG               i;
    PIRP                newIrp          = NULL;
    BOOLEAN             allocNewIrp     = FALSE;
    KEVENT              Event;
    IO_STATUS_BLOCK     ioStatus;
    
    ENTER("");

    TRACE(TL_TRACE, ("hResource = 0x%x\n", hResource));
    TRACE(TL_TRACE, ("nNumberOfDescriptors = 0x%x\n", nNumberOfDescriptors));
    TRACE(TL_TRACE, ("IsochDescriptor = 0x%x\n", IsochDescriptor));

    //
    // If this is a UserMode request create a newIrp so that the request
    // will be issued from KernelMode
    //
    if (Irp->RequestorMode == UserMode) {

        newIrp = IoBuildDeviceIoControlRequest (IOCTL_1394_CLASS, deviceExtension->StackDeviceObject, 
                            NULL, 0, NULL, 0, TRUE, &Event, &ioStatus);

        if (!newIrp) {

            TRACE(TL_ERROR, ("Failed to allocate newIrp!\n"));        
            ntStatus = STATUS_INSUFFICIENT_RESOURCES;
            goto Exit_IsochDetachBuffers;            
        }
        allocNewIrp = TRUE;
    }
    
    pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));

    if (!pIrb) {

        TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit_IsochDetachBuffers;
    } // if

    RtlZeroMemory (pIrb, sizeof (IRB));
    pIrb->FunctionNumber = REQUEST_ISOCH_DETACH_BUFFERS;
    pIrb->Flags = 0;
    pIrb->u.IsochDetachBuffers.hResource = hResource;
    pIrb->u.IsochDetachBuffers.nNumberOfDescriptors = nNumberOfDescriptors;
    pIrb->u.IsochDetachBuffers.pIsochDescriptor = IsochDescriptor;

    //
    // If we allocated this irp, submit it asynchronously and wait for its
    // completion event to be signaled.  Otherwise submit it synchronously
    //
    if (allocNewIrp) {

        KeInitializeEvent (&Event, NotificationEvent, FALSE);
        ntStatus = t1394_SubmitIrpAsync (deviceExtension->StackDeviceObject, newIrp, pIrb);

        if (ntStatus == STATUS_PENDING) {
            KeWaitForSingleObject (&Event, Executive, KernelMode, FALSE, NULL); 
            ntStatus = ioStatus.Status;
        }
    }
    else {
        ntStatus = t1394_SubmitIrpSynch(deviceExtension->StackDeviceObject, Irp, pIrb);
    }
    
    if (!NT_SUCCESS(ntStatus)) {

        TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", ntStatus));
    }
    else
    {
        // if we detached the descriptor, free up the allocations
        for (i=0; i<nNumberOfDescriptors; i++)
		{
			if (IsochDescriptor[i].Mdl)
			{
				IoFreeMdl(IsochDescriptor[i].Mdl);
			}
		}
        ExFreePool(IsochDescriptor);
    }

Exit_IsochDetachBuffers:

    if (pIrb)
    {
        ExFreePool(pIrb);
    }

    if (allocNewIrp)
    {
        Irp->IoStatus = ioStatus;
    }
        
    EXIT("t1394_IsochDetachBuffers", ntStatus);
    return(ntStatus);
} // t1394_IsochDetachBuffers

NTSTATUS
t1394_IsochFreeBandwidth(
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN HANDLE           hBandwidth
    )
{
    NTSTATUS            ntStatus        = STATUS_SUCCESS;
    PDEVICE_EXTENSION   deviceExtension = DeviceObject->DeviceExtension;
    PIRB                pIrb            = NULL;
    PIRP                newIrp          = NULL;
    BOOLEAN             allocNewIrp     = FALSE;
    KEVENT              Event;
    IO_STATUS_BLOCK     ioStatus;
    
    ENTER("t1394_IsochFreeBandwidth");

    TRACE(TL_TRACE, ("hBandwidth = 0x%x\n", hBandwidth));

    //
    // If this is a UserMode request create a newIrp so that the request
    // will be issued from KernelMode
    //
    if (Irp->RequestorMode == UserMode) {

        newIrp = IoBuildDeviceIoControlRequest (IOCTL_1394_CLASS, deviceExtension->StackDeviceObject, 
                            NULL, 0, NULL, 0, TRUE, &Event, &ioStatus);

        if (!newIrp) {

            TRACE(TL_ERROR, ("Failed to allocate newIrp!\n"));        
            ntStatus = STATUS_INSUFFICIENT_RESOURCES;
            goto Exit_IsochFreeBandwidth;            
        }
        allocNewIrp = TRUE;
    }
    
    pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));

    if (!pIrb) {

        TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit_IsochFreeBandwidth;
    } // if

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -