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

📄 isochapi.c

📁 winddk src目录下的WDM源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
            ntStatus = ioStatus.Status;
        }
    }
    else {
        ntStatus = t1394_SubmitIrpSynch(deviceExtension->StackDeviceObject, Irp, pIrb);
    }
 
    if (!NT_SUCCESS(ntStatus)) {

        TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", ntStatus));
    }
    
Exit_IsochStop:

    if (pIrb)
    {
        ExFreePool(pIrb);
    }

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

NTSTATUS
t1394_IsochTalk(
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN HANDLE           hResource,
    IN ULONG            fulFlags,
    CYCLE_TIME          StartTime
    )
{
    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_IsochTalk");

    TRACE(TL_TRACE, ("hResource = 0x%x\n", hResource));
    TRACE(TL_TRACE, ("fulFlags = 0x%x\n", fulFlags));
    TRACE(TL_TRACE, ("StartTime.CL_CycleOffset = 0x%x\n", StartTime.CL_CycleOffset));
    TRACE(TL_TRACE, ("StartTime.CL_CycleCount = 0x%x\n", StartTime.CL_CycleCount));
    TRACE(TL_TRACE, ("StartTime.CL_SecondCount = 0x%x\n", StartTime.CL_SecondCount));

    //
    // 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_IsochTalk;
        }
        allocNewIrp = TRUE;
    }
    
    pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));

    if (!pIrb) {

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

    RtlZeroMemory (pIrb, sizeof (IRB));
    pIrb->FunctionNumber = REQUEST_ISOCH_TALK;
    pIrb->Flags = 0;
    pIrb->u.IsochTalk.hResource = hResource;
    pIrb->u.IsochTalk.fulFlags = fulFlags;
    pIrb->u.IsochTalk.StartTime = StartTime;

    //
    // 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));
    }

Exit_IsochTalk:

    if (pIrb)
    {
        ExFreePool(pIrb);
    }

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

void
t1394_IsochCallback(
    IN PDEVICE_EXTENSION    DeviceExtension,
    IN PISOCH_DETACH_DATA   IsochDetachData
    )
{
    KIRQL               Irql;

    ENTER("t1394_IsochCallback");

    if (!IsochDetachData)
    {
        goto Exit_IsochCallback;
    }

    // make sure somebody else isn't already handling cleaning up for this request
    KeAcquireSpinLock(&DeviceExtension->IsochSpinLock, &Irql);
    if ((!DeviceExtension->bShutdown) &&
    	(t1394_IsOnList(&IsochDetachData->IsochDetachList, &DeviceExtension->IsochDetachData)))
    {

        RemoveEntryList(&IsochDetachData->IsochDetachList);
		KeReleaseSpinLock(&DeviceExtension->IsochSpinLock, Irql);
        KeCancelTimer(&IsochDetachData->Timer);

        TRACE(TL_TRACE, ("IsochCallback: IsochDetachData = 0x%x\n", IsochDetachData));
        TRACE(TL_TRACE, ("IsochCallback: IsochDetachData->Irp = 0x%x\n", IsochDetachData->Irp));
        TRACE(TL_TRACE, ("IsochCallback: IsochDetachData->newIrp = 0x%x\n", IsochDetachData->newIrp));

        // need to save the status of the attach
        // we'll clean up in the same spot for success's and timeout's
        IsochDetachData->AttachStatus = IsochDetachData->Irp->IoStatus.Status;
        t1394_IsochCleanup(IsochDetachData);
    }
    else
    {
    	TRACE(TL_TRACE, ("IsochCallback: Entry 0x%x not on List 0x%x\n", 
    		IsochDetachData->IsochDetachList, DeviceExtension->IsochDetachData));
    	KeReleaseSpinLock(&DeviceExtension->IsochSpinLock, Irql);
    }

Exit_IsochCallback:
    EXIT("t1394_IsochCallback", 0);
} // t1394_IsochCallback

void
t1394_IsochTimeout(
    IN PKDPC                Dpc,
    IN PISOCH_DETACH_DATA   IsochDetachData,
    IN PVOID                SystemArgument1,
    IN PVOID                SystemArgument2
    )
{
    KIRQL               Irql;
    PDEVICE_EXTENSION   DeviceExtension;

    ENTER("t1394_IsochTimeout");
    TRACE(TL_WARNING, ("Isoch Timeout!\n"));

	//
	// ISSUE: the device extension we are referencing comes from the IsochDetachData
	// but it is possible this memory has been freed before we enter this function.
	// The only way to check is to validate against our DeviceExtension->IsochDetachList
	// but if the IsochDetachData has been freed then that won't be accessible
	//
    DeviceExtension = IsochDetachData->DeviceExtension;
    if (DeviceExtension) 
    {
    	// make sure nobody else has already handled this request yet
        KeAcquireSpinLock(&DeviceExtension->IsochSpinLock, &Irql);
		if (t1394_IsOnList(&IsochDetachData->IsochDetachList, &DeviceExtension->IsochDetachData))
		{
        	RemoveEntryList(&IsochDetachData->IsochDetachList);
        	KeReleaseSpinLock(&DeviceExtension->IsochSpinLock, Irql);

        	
        	if(KeCancelTimer(&IsochDetachData->Timer))
        	{

        	    TRACE(TL_TRACE, ("IsochTimeout: IsochDetachData = 0x%x\n", IsochDetachData));
	            TRACE(TL_TRACE, ("IsochTimeout: IsochDetachData->Irp = 0x%x\n", IsochDetachData->Irp));
	            TRACE(TL_TRACE, ("IsochTimeout: IsochDetachData->newIrp = 0x%x\n", IsochDetachData->newIrp));

	            // need to save the status of the attach
	            // we'll clean up in the same spot for success's and timeout's
	            IsochDetachData->AttachStatus = STATUS_TIMEOUT;
	            t1394_IsochCleanup(IsochDetachData);
	        }
		}
		else
		{
			KeReleaseSpinLock(&DeviceExtension->IsochSpinLock, Irql);
		}
    }

    EXIT("t1394_IsochTimeout", 0);
} // t1394_IsochTimeout

void
t1394_IsochCleanup(
    IN PISOCH_DETACH_DATA   IsochDetachData
    )
{
    ULONG               i;
    PDEVICE_EXTENSION   DeviceExtension;

    ENTER("t1394_IsochCleanup");

    DeviceExtension = IsochDetachData->DeviceExtension;

    //
    // see if we need to detach this buffer
    //
    if ((!IsochDetachData) || (!DeviceExtension))
    {
        goto Exit_IsochDetachBuffers;
    }
    
    if (IsochDetachData->bDetach) {

        PIRB                pIrb;
        NTSTATUS            ntStatus;
        PIO_STACK_LOCATION  NextIrpStack;

        pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));

        if (!pIrb) {

            TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
            TRACE(TL_WARNING, ("Can't detach buffer!\n"));
            ntStatus = STATUS_INSUFFICIENT_RESOURCES;
            goto Exit_IsochDetachBuffers;
        } // if

        // save the irb in our detach data context
        IsochDetachData->DetachIrb = pIrb;

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

        NextIrpStack = IoGetNextIrpStackLocation(IsochDetachData->newIrp);        
        NextIrpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
        NextIrpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_1394_CLASS;
        NextIrpStack->Parameters.Others.Argument1 = pIrb;

        IoSetCompletionRoutine( IsochDetachData->newIrp,
                                t1394_IsochDetachCompletionRoutine,
                                IsochDetachData,
                                TRUE,
                                TRUE,
                                TRUE
                                );

        IoCallDriver(DeviceExtension->StackDeviceObject, IsochDetachData->newIrp);
    }
    else {

        TRACE(TL_TRACE, ("Complete Irp.\n"));

        if (IsochDetachData->AttachIrb)
        {
            ExFreePool(IsochDetachData->AttachIrb);
        }

        for (i=0; i<IsochDetachData->numIsochDescriptors; i++)
        {
            if (IsochDetachData->IsochDescriptor[i].Mdl)
            {
                IoFreeMdl(IsochDetachData->IsochDescriptor[i].Mdl);
            }
        }

        ExFreePool(IsochDetachData->IsochDescriptor);

        IsochDetachData->Irp->IoStatus.Status = IsochDetachData->AttachStatus;

        // only set this if its a success...
        if (NT_SUCCESS(IsochDetachData->AttachStatus))
        {
            IsochDetachData->Irp->IoStatus.Information = IsochDetachData->outputBufferLength;
        }

        //
        // Complete original Irp and free the one we allocated in
        // IsochAttachBuffers
        //
        IoCompleteRequest(IsochDetachData->Irp, IO_NO_INCREMENT);
        IoFreeIrp (IsochDetachData->newIrp);

        // all done with IsochDetachData, lets deallocate it...
        ExFreePool(IsochDetachData);
    }

Exit_IsochDetachBuffers:

    EXIT("t1394_IsochCleanup", 0);
} // t1394_IsochCleanup

NTSTATUS
t1394_IsochDetachCompletionRoutine(
    IN PDEVICE_OBJECT       DeviceObject,
    IN PIRP                 Irp,
    IN PISOCH_DETACH_DATA   IsochDetachData
    )
{
    NTSTATUS        ntStatus = STATUS_SUCCESS;
    ULONG           i;

    ENTER("t1394_IsochDetachCompletionRoutine");

    if (!IsochDetachData) {

        TRACE(TL_WARNING, ("Invalid IsochDetachData\n"));
        goto Exit_IsochDetachCompletionRoutine;
    }

    if (IsochDetachData->DetachIrb)
    {
        ExFreePool(IsochDetachData->DetachIrb);
    }
    TRACE(TL_TRACE, ("Now lets complete the Irp.\n"));

    if (IsochDetachData->AttachIrb)
        ExFreePool(IsochDetachData->AttachIrb);

    for (i=0; i<IsochDetachData->numIsochDescriptors; i++)
    {

        if (IsochDetachData->IsochDescriptor[i].Mdl)
        {
            IoFreeMdl(IsochDetachData->IsochDescriptor[i].Mdl);
        }
    }

    if (IsochDetachData->IsochDescriptor)
    {
        ExFreePool(IsochDetachData->IsochDescriptor);
    }
    
    // only set this if its a success...
    if (NT_SUCCESS(IsochDetachData->AttachStatus))
    {
        IsochDetachData->Irp->IoStatus.Information = IsochDetachData->outputBufferLength;
    }
    
    IsochDetachData->Irp->IoStatus.Status = IsochDetachData->AttachStatus;

    //
    // Complete original Irp and free the one we allocated in
    // IsochAttachBuffers
    //
    IoCompleteRequest(IsochDetachData->Irp, IO_NO_INCREMENT);
    IoFreeIrp (IsochDetachData->newIrp);

    // all done with IsochDetachData, lets deallocate it...
    if (IsochDetachData)
    {
        ExFreePool(IsochDetachData);
    }
    
Exit_IsochDetachCompletionRoutine:

    EXIT(

⌨️ 快捷键说明

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